| 1 | 1 | def answer(question: str) -> int: |
| 2 | | pass |
| 2 | # Edge Case: Empty or None input |
| 3 | if not question: |
| 4 | raise ValueError("syntax error") |
| 5 | |
| 6 | # Edge Case: Question doesn't start with "What is" |
| 7 | if not question.startswith("What is"): |
| 8 | raise ValueError("unknown operation") |
| 9 | |
| 10 | # Remove the "What is" prefix and the trailing question mark |
| 11 | expression = question[8:-1].strip() |
| 12 | |
| 13 | # Edge Case: Empty expression after removing prefix and question mark |
| 14 | if not expression: |
| 15 | raise ValueError("syntax error") |
| 16 | |
| 17 | # Tokenize the expression |
| 18 | tokens = [] |
| 19 | i = 0 |
| 20 | while i < len(expression): |
| 21 | if expression[i].isspace(): |
| 22 | i += 1 |
| 23 | continue |
| 24 | elif expression[i].isdigit() or (expression[i] == '-' and i < len(expression) - 1 and expression[i+1].isdigit()): |
| 25 | # Parse number (including negative numbers) |
| 26 | start = i |
| 27 | if expression[i] == '-': |
| 28 | i += 1 |
| 29 | while i < len(expression) and (expression[i].isdigit() or expression[i] == '.'): |
| 30 | i += 1 |
| 31 | # Edge Case: Invalid number format (e.g., "5.") |
| 32 | if expression[start:i].endswith('.'): |
| 33 | raise ValueError("syntax error") |
| 34 | try: |
| 35 | num = int(expression[start:i]) |
| 36 | tokens.append(num) |
| 37 | except ValueError: |
| 38 | raise ValueError("syntax error") |
| 39 | elif expression[i:].startswith("plus"): |
| 40 | tokens.append("+") |
| 41 | i += 4 |
| 42 | elif expression[i:].startswith("minus"): |
| 43 | tokens.append("-") |
| 44 | i += 5 |
| 45 | elif expression[i:].startswith("multiplied by"): |
| 46 | tokens.append("*") |
| 47 | i += 13 |
| 48 | elif expression[i:].startswith("divided by"): |
| 49 | tokens.append("/") |
| 50 | i += 10 |
| 51 | else: |
| 52 | # Edge Case: Unknown operation |
| 53 | raise ValueError("unknown operation") |
| 54 | |
| 55 | # Edge Case: Expression with no tokens |
| 56 | if not tokens: |
| 57 | raise ValueError("syntax error") |
| 58 | |
| 59 | # Edge Case: Expression starting with an operator |
| 60 | if isinstance(tokens[0], str): |
| 61 | raise ValueError("syntax error") |
| 62 | |
| 63 | # Evaluate the expression from left to right |
| 64 | result = tokens[0] |
| 65 | i = 1 |
| 66 | |
| 67 | # Edge Case: Odd number of tokens (missing operator or operand) |
| 68 | if len(tokens) % 2 == 0: |
| 69 | raise ValueError("syntax error") |
| 70 | |
| 71 | while i < len(tokens): |
| 72 | # Edge Case: Missing operator |
| 73 | if not isinstance(tokens[i], str): |
| 74 | raise ValueError("syntax error") |
| 75 | |
| 76 | operator = tokens[i] |
| 77 | |
| 78 | # Edge Case: Missing operand |
| 79 | if i + 1 >= len(tokens) or isinstance(tokens[i + 1], str): |
| 80 | raise ValueError("syntax error") |
| 81 | |
| 82 | operand = tokens[i + 1] |
| 83 | |
| 84 | if operator == "+": |
| 85 | result += operand |
| 86 | elif operator == "-": |
| 87 | result -= operand |
| 88 | elif operator == "*": |
| 89 | result *= operand |
| 90 | elif operator == "/": |
| 91 | # Edge Case: Division by zero |
| 92 | if operand == 0: |
| 93 | raise ValueError("syntax error") # Or we could raise ZeroDivisionError |
| 94 | result //= operand # Integer division as per examples |
| 95 | else: |
| 96 | # Edge Case: Unknown operator (should not happen with current parsing) |
| 97 | raise ValueError("unknown operation") |
| 98 | |
| 99 | i += 2 |
| 100 | |
| 101 | return result |
| 102 | # Handled Edge Cases: Empty input, None input, question not starting with "What is", empty expression after parsing, invalid number format, unknown operations, expression with no tokens, expression starting with operator, odd number of tokens, missing operators, missing operands, division by zero |