Buckets:
| import random | |
| import regex | |
| import re | |
| import sympy | |
| from typing import TypeVar, Iterable, List, Union, Any, Dict | |
| from word2number import w2n | |
| def _fix_fracs(string): | |
| substrs = string.split("\\frac") | |
| new_str = substrs[0] | |
| if len(substrs) > 1: | |
| substrs = substrs[1:] | |
| for substr in substrs: | |
| new_str += "\\frac" | |
| if len(substr) > 0 and substr[0] == "{": | |
| new_str += substr | |
| else: | |
| try: | |
| assert len(substr) >= 2 | |
| except: | |
| return string | |
| if substr.startswith("\\pi"): | |
| try: | |
| assert len(substr) >= 4 | |
| except: | |
| return string | |
| a = substr[:3] | |
| b = substr[3] | |
| if len(substr) > 4: | |
| post_substr = substr[4:] | |
| else: | |
| post_substr = "" | |
| else: | |
| a = substr[0] | |
| b = substr[1] | |
| if len(substr) > 2: | |
| post_substr = substr[2:] | |
| else: | |
| post_substr = "" | |
| if b != "{": | |
| new_str += "{" + a + "}{" + b + "}" + post_substr | |
| else: | |
| new_str += "{" + a + "}" + b + post_substr | |
| string = new_str | |
| return string | |
| def _fix_a_slash_b(string): | |
| if len(string.split("/")) != 2: | |
| return string | |
| a = string.split("/")[0] | |
| b = string.split("/")[1] | |
| try: | |
| if "sqrt" not in a: | |
| a = int(a) | |
| if "sqrt" not in b: | |
| b = int(b) | |
| assert string == "{}/{}".format(a, b) | |
| new_string = "\\frac{" + str(a) + "}{" + str(b) + "}" | |
| return new_string | |
| except: | |
| return string | |
| def _fix_sqrt(string): | |
| _string = re.sub(r"\\sqrt(\w+)", r"\\sqrt{\1}", string) | |
| return _string | |
| def convert_word_number(text: str) -> str: | |
| try: | |
| text = str(w2n.word_to_num(text)) | |
| except: | |
| pass | |
| return text | |
| # units mainly from MathQA | |
| unit_texts = [ | |
| "east", | |
| "degree", | |
| "mph", | |
| "kmph", | |
| "ft", | |
| "m sqaure", | |
| " m east", | |
| "sq m", | |
| "deg", | |
| "mile", | |
| "q .", | |
| "monkey", | |
| "prime", | |
| "ratio", | |
| "profit of rs", | |
| "rd", | |
| "o", | |
| "gm", | |
| "p . m", | |
| "lb", | |
| "tile", | |
| "per", | |
| "dm", | |
| "lt", | |
| "gain", | |
| "ab", | |
| "way", | |
| "west", | |
| "a .", | |
| "b .", | |
| "c .", | |
| "d .", | |
| "e .", | |
| "f .", | |
| "g .", | |
| "h .", | |
| "t", | |
| "a", | |
| "h", | |
| "no change", | |
| "men", | |
| "soldier", | |
| "pie", | |
| "bc", | |
| "excess", | |
| "st", | |
| "inches", | |
| "noon", | |
| "percent", | |
| "by", | |
| "gal", | |
| "kmh", | |
| "c", | |
| "acre", | |
| "rise", | |
| "a . m", | |
| "th", | |
| "π r 2", | |
| "sq", | |
| "mark", | |
| "l", | |
| "toy", | |
| "coin", | |
| "sq . m", | |
| "gallon", | |
| "° f", | |
| "profit", | |
| "minw", | |
| "yr", | |
| "women", | |
| "feet", | |
| "am", | |
| "pm", | |
| "hr", | |
| "cu cm", | |
| "square", | |
| "v â € ™", | |
| "are", | |
| "rupee", | |
| "rounds", | |
| "cubic", | |
| "cc", | |
| "mtr", | |
| "s", | |
| "ohm", | |
| "number", | |
| "kmph", | |
| "day", | |
| "hour", | |
| "minute", | |
| "min", | |
| "second", | |
| "man", | |
| "woman", | |
| "sec", | |
| "cube", | |
| "mt", | |
| "sq inch", | |
| "mp", | |
| "∏ cm ³", | |
| "hectare", | |
| "more", | |
| "sec", | |
| "unit", | |
| "cu . m", | |
| "cm 2", | |
| "rs .", | |
| "rs", | |
| "kg", | |
| "g", | |
| "month", | |
| "km", | |
| "m", | |
| "cm", | |
| "mm", | |
| "apple", | |
| "liter", | |
| "loss", | |
| "yard", | |
| "pure", | |
| "year", | |
| "increase", | |
| "decrease", | |
| "d", | |
| "less", | |
| "Surface", | |
| "litre", | |
| "pi sq m", | |
| "s .", | |
| "metre", | |
| "meter", | |
| "inch", | |
| ] | |
| unit_texts.extend([t + "s" for t in unit_texts]) | |
| def strip_string(string, skip_unit=False): | |
| string = str(string).strip() | |
| # linebreaks | |
| string = string.replace("\n", "") | |
| # right "." | |
| string = string.rstrip(".") | |
| # remove inverse spaces | |
| # replace \\ with \ | |
| string = string.replace("\\!", "") | |
| # string = string.replace("\\ ", "") | |
| # string = string.replace("\\\\", "\\") | |
| # matrix | |
| string = re.sub(r"\\begin\{array\}\{.*?\}", r"\\begin{pmatrix}", string) | |
| string = re.sub(r"\\end\{array\}", r"\\end{pmatrix}", string) | |
| string = string.replace("bmatrix", "pmatrix") | |
| # replace tfrac and dfrac with frac | |
| string = string.replace("tfrac", "frac") | |
| string = string.replace("dfrac", "frac") | |
| string = ( | |
| string.replace("\\neq", "\\ne") | |
| .replace("\\leq", "\\le") | |
| .replace("\\geq", "\\ge") | |
| ) | |
| # remove \left and \right | |
| string = string.replace("\\left", "") | |
| string = string.replace("\\right", "") | |
| string = string.replace("\\{", "{") | |
| string = string.replace("\\}", "}") | |
| # Remove unit: miles, dollars if after is not none | |
| _string = re.sub(r"\\text{.*?}$", "", string).strip() | |
| if _string != "" and _string != string: | |
| # print("Warning: unit not removed: '{}' -> '{}'".format(string, _string)) | |
| string = _string | |
| if not skip_unit: | |
| # Remove unit: texts | |
| for _ in range(2): | |
| for unit_text in unit_texts: | |
| # use regex, the prefix should be either the start of the string or a non-alphanumeric character | |
| # the suffix should be either the end of the string or a non-alphanumeric character | |
| _string = re.sub(r"(^|\W)" + unit_text + r"($|\W)", r"\1\2", string) | |
| if _string != "": | |
| string = _string | |
| # Remove circ (degrees) | |
| string = string.replace("^{\\circ}", "") | |
| string = string.replace("^\\circ", "") | |
| # remove dollar signs | |
| string = string.replace("\\$", "") | |
| string = string.replace("$", "") | |
| string = string.replace("\\(", "").replace("\\)", "") | |
| # convert word number to digit | |
| string = convert_word_number(string) | |
| # replace "\\text{...}" to "..." | |
| string = re.sub(r"\\text\{(.*?)\}", r"\1", string) | |
| for key in ["x=", "y=", "z=", "x\\in", "y\\in", "z\\in", "x\\to", "y\\to", "z\\to"]: | |
| if string.startswith(key): | |
| string = string.replace(key, "") | |
| string = string.replace("\\emptyset", r"{}") | |
| string = string.replace("(-\\infty,\\infty)", "\\mathbb{R}") | |
| # remove percentage | |
| string = string.replace("\\%", "") | |
| string = string.replace("\%", "") | |
| string = string.replace("%", "") | |
| # " 0." equivalent to " ." and "{0." equivalent to "{." Alternatively, add "0" if "." is the start of the string | |
| string = string.replace(" .", " 0.") | |
| string = string.replace("{.", "{0.") | |
| # cdot | |
| # string = string.replace("\\cdot", "") | |
| if ( | |
| string.startswith("{") | |
| and string.endswith("}") | |
| and string.isalnum() | |
| or string.startswith("(") | |
| and string.endswith(")") | |
| and string.isalnum() | |
| or string.startswith("[") | |
| and string.endswith("]") | |
| and string.isalnum() | |
| ): | |
| string = string[1:-1] | |
| # inf | |
| string = string.replace("infinity", "\\infty") | |
| if "\\infty" not in string: | |
| string = string.replace("inf", "\\infty") | |
| string = string.replace("+\\inity", "\\infty") | |
| # and | |
| string = string.replace("and", "") | |
| string = string.replace("\\mathbf", "") | |
| # use regex to remove \mbox{...} | |
| string = re.sub(r"\\mbox{.*?}", "", string) | |
| # quote | |
| string.replace("'", "") | |
| string.replace('"', "") | |
| # i, j | |
| if "j" in string and "i" not in string: | |
| string = string.replace("j", "i") | |
| # replace a.000b where b is not number or b is end, with ab, use regex | |
| string = re.sub(r"(\d+)\.0*([^\d])", r"\1\2", string) | |
| string = re.sub(r"(\d+)\.0*$", r"\1", string) | |
| # if empty, return empty string | |
| if len(string) == 0: | |
| return string | |
| if string[0] == ".": | |
| string = "0" + string | |
| # to consider: get rid of e.g. "k = " or "q = " at beginning | |
| if len(string.split("=")) == 2: | |
| if len(string.split("=")[0]) <= 2: | |
| string = string.split("=")[1] | |
| string = _fix_sqrt(string) | |
| string = string.replace(" ", "") | |
| # \frac1b or \frac12 --> \frac{1}{b} and \frac{1}{2}, etc. Even works with \frac1{72} (but not \frac{72}1). Also does a/b --> \\frac{a}{b} | |
| string = _fix_fracs(string) | |
| # NOTE: X/Y changed to \frac{X}{Y} in dataset, but in simple cases fix in case the model output is X/Y | |
| string = _fix_a_slash_b(string) | |
| return string | |
| def find_box(pred_str: str): | |
| ans = pred_str.split("boxed")[-1] | |
| if not ans: | |
| return "" | |
| if ans[0] == "{": | |
| stack = 1 | |
| a = "" | |
| for c in ans[1:]: | |
| if c == "{": | |
| stack += 1 | |
| a += c | |
| elif c == "}": | |
| stack -= 1 | |
| if stack == 0: | |
| break | |
| a += c | |
| else: | |
| a += c | |
| else: | |
| a = ans.split("$")[0].strip() | |
| return a | |
| def clean_units(pred_str: str): | |
| """Clean the units in the number.""" | |
| def convert_pi_to_number(code_string): | |
| code_string = code_string.replace("\\pi", "π") | |
| # Replace \pi or π not preceded by a digit or } with 3.14 | |
| code_string = re.sub(r"(?<![\d}])\\?π", "3.14", code_string) | |
| # Replace instances where π is preceded by a digit but without a multiplication symbol, e.g., "3π" -> "3*3.14" | |
| code_string = re.sub(r"(\d)(\\?π)", r"\1*3.14", code_string) | |
| # Handle cases where π is within braces or followed by a multiplication symbol | |
| # This replaces "{π}" with "3.14" directly and "3*π" with "3*3.14" | |
| code_string = re.sub(r"\{(\\?π)\}", "3.14", code_string) | |
| code_string = re.sub(r"\*(\\?π)", "*3.14", code_string) | |
| return code_string | |
| pred_str = convert_pi_to_number(pred_str) | |
| pred_str = pred_str.replace("%", "/100") | |
| pred_str = pred_str.replace("$", "") | |
| pred_str = pred_str.replace("¥", "") | |
| pred_str = pred_str.replace("°C", "") | |
| pred_str = pred_str.replace(" C", "") | |
| pred_str = pred_str.replace("°", "") | |
| return pred_str | |
| def extract_answer(pred_str, use_last_number=True): | |
| pred_str = pred_str.replace("\u043a\u0438", "") | |
| if "final answer is $" in pred_str and "$. I hope" in pred_str: | |
| # minerva_math | |
| tmp = pred_str.split("final answer is $", 1)[1] | |
| pred = tmp.split("$. I hope", 1)[0].strip() | |
| elif "boxed" in pred_str: | |
| ans = pred_str.split("boxed")[-1] | |
| if len(ans) == 0: | |
| return "" | |
| elif ans[0] == "{": | |
| stack = 1 | |
| a = "" | |
| for c in ans[1:]: | |
| if c == "{": | |
| stack += 1 | |
| a += c | |
| elif c == "}": | |
| stack -= 1 | |
| if stack == 0: | |
| break | |
| a += c | |
| else: | |
| a += c | |
| else: | |
| a = ans.split("$")[0].strip() | |
| pred = a | |
| elif "he answer is" in pred_str: | |
| pred = pred_str.split("he answer is")[-1].strip() | |
| elif "final answer is" in pred_str: | |
| pred = pred_str.split("final answer is")[-1].strip() | |
| elif "答案是" in pred_str: | |
| # Handle Chinese few-shot multiple choice problem answer extraction | |
| pred = pred_str.split("答案是")[1].strip().split("\n\n")[0].strip() | |
| else: # use the last number | |
| if use_last_number: | |
| pattern = "-?\d*\.?\d+" | |
| pred = re.findall(pattern, pred_str.replace(",", "")) | |
| if len(pred) >= 1: | |
| pred = pred[-1] | |
| else: | |
| pred = "" | |
| else: | |
| pred = "" | |
| pred = re.sub(r"\n\s*", "", pred) | |
| if pred != "" and pred[0] == ":": | |
| pred = pred[1:] | |
| if pred != "" and pred[-1] == ".": | |
| pred = pred[:-1] | |
| if pred != "" and pred[-1] == "/": | |
| pred = pred[:-1] | |
| pred = strip_string(pred, skip_unit=False) | |
| return pred | |
| def extract_boxed_answer(pred_str, use_last_number=True): | |
| pred_str = pred_str.replace("\u043a\u0438", "") | |
| if "boxed" in pred_str: | |
| ans = pred_str.split("boxed")[-1] | |
| if len(ans) == 0: | |
| return "" | |
| elif ans[0] == "{": | |
| stack = 1 | |
| a = "" | |
| for c in ans[1:]: | |
| if c == "{": | |
| stack += 1 | |
| a += c | |
| elif c == "}": | |
| stack -= 1 | |
| if stack == 0: | |
| break | |
| a += c | |
| else: | |
| a += c | |
| else: | |
| a = ans.split("$")[0].strip() | |
| pred = a | |
| else: # use the last number | |
| if use_last_number: | |
| pattern = "-?\d*\.?\d+" | |
| pred = re.findall(pattern, pred_str.replace(",", "")) | |
| if len(pred) >= 1: | |
| pred = pred[-1] | |
| else: | |
| pred = "" | |
| else: | |
| pred = "" | |
| pred = re.sub(r"\n\s*", "", pred) | |
| if pred != "" and pred[0] == ":": | |
| pred = pred[1:] | |
| if pred != "" and pred[-1] == ".": | |
| pred = pred[:-1] | |
| if pred != "" and pred[-1] == "/": | |
| pred = pred[:-1] | |
| pred = strip_string(pred, skip_unit=False) | |
| return pred | |
| STRIP_EXCEPTIONS = ["carp_en", "minerva_math"] | |
| def parse_ground_truth(answer: str): | |
| gt_cot = answer | |
| gt_ans = extract_answer(answer) | |
| # parse ground truth | |
| # post process | |
| gt_cot = str(gt_cot).strip() | |
| gt_ans = strip_string(gt_ans, skip_unit=False) | |
| return gt_cot, gt_ans | |
| if __name__ == '__main__': | |
| print(extract_answer('For the piecewise function to be continuous, the cases must \"meet\" at $2$ and $-2$. For example, $ax+3$ and $x-5$ must be equal when $x=2$. This implies $a(2)+3=2-5$, which we solve to get $2a=-6 \\Rightarrow a=-3$. Similarly, $x-5$ and $2x-b$ must be equal when $x=-2$. Substituting, we get $-2-5=2(-2)-b$, which implies $b=3$. So $a+b=-3+3=\\boxed{0}$.')) |
Xet Storage Details
- Size:
- 14 kB
- Xet hash:
- f197433c71892ef6c9d589b6b6b661072a8af38bb4e3163cd00f18749f5a8f58
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.