22from .feedback .symbolic_comparison import feedback_generators as symbolic_feedback_generators
33from .criteria_graph_utilities import CriteriaGraph
44
5+ is_nonnegative_number_regex = '((0|[1-9]\d*)?(\.\d+)?(?<=\d)(e-?(0|[1-9]\d*))?)'
56is_number_regex = '(-?(0|[1-9]\d*)?(\.\d+)?(?<=\d)(e-?(0|[1-9]\d*))?)'
67
78def is_number (string ):
@@ -25,22 +26,67 @@ def escape_regex_reserved_characters(string):
2526 string = string .replace (s ,'\\ ' + s )
2627 return string
2728
29+ #def generate_arbitrary_number_pattern_matcher(string):
30+ # non_numbers = []
31+ # number = re.search(is_number_regex, string)
32+ # start = 0
33+ # end = 0
34+ # offset = 0
35+ # while number is not None:
36+ # start, end = number.span()
37+ # start += offset
38+ # end += offset
39+ # non_number = escape_regex_reserved_characters(string[offset:start])
40+ # non_number = ''.join(non_number.split())
41+ # non_numbers.append(non_number)
42+ # offset = end
43+ # number = re.search(is_number_regex, string[offset:])
44+ # non_numbers.append(string[offset:])
45+ # pattern = is_number_regex.join(non_numbers)
46+ # def matcher(comp_string):
47+ # comp_string = ''.join(comp_string.split())
48+ # result = re.fullmatch(pattern, comp_string)
49+ # return result is not None
50+ # return matcher
51+
2852def generate_arbitrary_number_pattern_matcher (string ):
2953 non_numbers = []
30- number = re .search (is_number_regex , string )
54+ number_pattern = '(\\ (' + is_number_regex + '\\ ))'
55+ nonneg_number_pattern = is_nonnegative_number_regex
56+ #number_pattern = '('+'(\\\\('+is_number_regex+'\\\\))'+'|'+is_nonnegative_number_regex+')'
57+ full_pattern = '(' + number_pattern + '|' + nonneg_number_pattern + ')'
58+ number = re .search (number_pattern , string )
59+ nonneg_number = re .search (nonneg_number_pattern , string )
3160 start = 0
3261 end = 0
3362 offset = 0
34- while number is not None :
35- start , end = number .span ()
63+ while (number is not None ) or (nonneg_number is not None ):
64+ start_number = len (string )
65+ end_number = len (string )
66+ start_nonneg_number = len (string )
67+ end_nonneg_number = len (string )
68+ if number is not None :
69+ start_number , end_number = number .span ()
70+ if nonneg_number is not None :
71+ start_nonneg_number , end_nonneg_number = nonneg_number .span ()
72+ if start_number < start_nonneg_number :
73+ start , end = number .span ()
74+ else :
75+ start , end = nonneg_number .span ()
3676 start += offset
3777 end += offset
38- non_numbers .append (escape_regex_reserved_characters (string [offset :start ]))
78+ non_number = escape_regex_reserved_characters (string [offset :start ])
79+ if len (non_number ) > 0 :
80+ non_number = '(' + non_number + ')'
81+ non_number = '' .join (non_number .split ())
82+ non_numbers .append (non_number )
3983 offset = end
40- number = re .search (is_number_regex , string [offset :])
84+ number = re .search (number_pattern , string [offset :])
85+ nonneg_number = re .search (nonneg_number_pattern , string [offset :])
4186 non_numbers .append (string [offset :])
42- pattern = is_number_regex .join (non_numbers )
87+ pattern = full_pattern .join (non_numbers )
4388 def matcher (comp_string ):
89+ comp_string = '' .join (comp_string .split ())
4490 result = re .fullmatch (pattern , comp_string )
4591 return result is not None
4692 return matcher
@@ -97,4 +143,16 @@ def inner(unused_input):
97143 else :
98144 matches_found .add (label + "_FALSE" )
99145 return matches_found
100- return inner
146+ return inner
147+
148+ def written_as (comp , ref , parameters_dict ):
149+ if ref == "answer" :
150+ ref = parameters_dict ["original_input" ]["answer" ]
151+ elif ref == "response" :
152+ ref = parameters_dict ["original_input" ]["response" ]
153+ if comp == "answer" :
154+ comp = parameters_dict ["original_input" ]["answer" ]
155+ elif comp == "response" :
156+ comp = parameters_dict ["original_input" ]["response" ]
157+ matcher = generate_arbitrary_number_pattern_matcher (ref )
158+ return matcher (comp )
0 commit comments