Download tools/text_transform.py from ykumar2020/gaia-final-assignment: direct link, hf CLI and curl.
- Browser
- Download file 3.72 kB
-
https://huggingface.co/spaces/ykumar2020/gaia-final-assignment/resolve/main/tools/text_transform.py
- Command line
-
hf download hf://spaces/ykumar2020/gaia-final-assignment/tools/text_transform.py
-
curl -L -o text_transform.py https://huggingface.co/spaces/ykumar2020/gaia-final-assignment/resolve/main/tools/text_transform.py
3.72 kB
| """Deterministic text transformations.""" | |
| from __future__ import annotations | |
| import ast | |
| import codecs | |
| import operator | |
| import re | |
| _ARITHMETIC = { | |
| ast.Add: operator.add, | |
| ast.Sub: operator.sub, | |
| ast.Mult: operator.mul, | |
| ast.Div: operator.truediv, | |
| ast.FloorDiv: operator.floordiv, | |
| ast.Mod: operator.mod, | |
| ast.Pow: operator.pow, | |
| ast.USub: operator.neg, | |
| ast.UAdd: operator.pos, | |
| } | |
| _OPPOSITES = { | |
| "left": "right", | |
| "right": "left", | |
| "up": "down", | |
| "down": "up", | |
| "true": "false", | |
| "false": "true", | |
| "yes": "no", | |
| "no": "yes", | |
| "open": "closed", | |
| "closed": "open", | |
| } | |
| def _safe_arithmetic(expression: str) -> int | float: | |
| def evaluate(node): | |
| if isinstance(node, ast.Expression): | |
| return evaluate(node.body) | |
| if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)): | |
| return node.value | |
| if isinstance(node, ast.BinOp) and type(node.op) in _ARITHMETIC: | |
| return _ARITHMETIC[type(node.op)](evaluate(node.left), evaluate(node.right)) | |
| if isinstance(node, ast.UnaryOp) and type(node.op) in _ARITHMETIC: | |
| return _ARITHMETIC[type(node.op)](evaluate(node.operand)) | |
| raise ValueError("Unsafe arithmetic expression") | |
| return evaluate(ast.parse(expression, mode="eval")) | |
| def solve_text_transformation(question: str) -> str | None: | |
| """Solve transformations only when the operation is unambiguous.""" | |
| reversed_question = question[::-1] | |
| lower_reversed = reversed_question.lower() | |
| if "write" in lower_reversed and "answer" in lower_reversed: | |
| # The reversed prompt itself contains the literal instruction and answer. | |
| quoted = re.findall(r'["β]([^"β]+)["β]', reversed_question) | |
| if quoted: | |
| literal = quoted[-1] | |
| if "opposite" in lower_reversed: | |
| return _OPPOSITES.get(literal.casefold()) | |
| return literal | |
| match = re.search(r"write\s+(?:the\s+)?(?:word\s+)?([a-z-]+)", lower_reversed) | |
| if match: | |
| return match.group(1) | |
| quoted = re.findall(r'["β]([^"β]+)["β]', question) | |
| source = quoted[0] if quoted else None | |
| lowered = question.lower() | |
| if source and re.search(r"\breverse\b", lowered): | |
| return source[::-1] | |
| if source and re.search(r"\buppercase\b", lowered): | |
| return source.upper() | |
| if source and re.search(r"\blowercase\b", lowered): | |
| return source.lower() | |
| if source and re.search(r"\balphabeti[sz]e\b", lowered): | |
| return " ".join(sorted(source.split(), key=str.casefold)) | |
| if source and re.search(r"\brot\s*-?13\b", lowered): | |
| return codecs.decode(source, "rot_13") | |
| if source and re.search(r"\bsort\b.*\bnumeric", lowered): | |
| numbers = re.findall(r"[-+]?\d+(?:\.\d+)?", source) | |
| return ", ".join(sorted(numbers, key=float)) | |
| arithmetic = re.search( | |
| r"(?:calculate|compute|evaluate|what is)\s+([\d\s+*/().%-]+)\??\s*$", | |
| question, | |
| re.IGNORECASE, | |
| ) | |
| if arithmetic: | |
| result = _safe_arithmetic(arithmetic.group(1).strip()) | |
| return ( | |
| str(int(result)) | |
| if isinstance(result, float) and result.is_integer() | |
| else str(result) | |
| ) | |
| extraction = re.search( | |
| r"extract\s+the\s+(\d+)(?:st|nd|rd|th)\s+word\s+from\s+[\"β]([^\"β]+)", | |
| question, | |
| re.IGNORECASE, | |
| ) | |
| if extraction: | |
| index = int(extraction.group(1)) - 1 | |
| words = extraction.group(2).split() | |
| return words[index] if 0 <= index < len(words) else None | |
| return None | |