|
1 | 1 | # worker.py |
2 | 2 | from pyscript import sync |
| 3 | +import json |
3 | 4 | import ast |
4 | | -challenge = sync.challenge |
| 5 | + |
5 | 6 | op_symbol_map = { |
6 | 7 | ast.Add: '+', |
7 | 8 | ast.Sub: '-', |
@@ -30,45 +31,64 @@ def symbol_lookup(key, by_symbol=True): |
30 | 31 | else: |
31 | 32 | return op_symbol_map[key] |
32 | 33 |
|
33 | | -def check_rules(code): |
| 34 | +def check_rules(code, config): |
34 | 35 | try: |
35 | 36 | tree = ast.parse(code) |
36 | 37 | except SyntaxError: |
37 | 38 | return False # syntax errors will be caught later |
38 | 39 |
|
39 | | - forbidden_ops = [symbol_lookup(s) for s in challenge("forbidden_operators")] |
| 40 | + forbidden_ops = [symbol_lookup(s) for s in config["forbidden_operators"]] |
40 | 41 | for node in ast.walk(tree): |
41 | 42 | if isinstance(node, ast.BinOp) or isinstance(node, ast.AugAssign): |
42 | 43 | for op in forbidden_ops: |
43 | 44 | if isinstance(node.op, op): |
44 | 45 | return True, symbol_lookup(type(node.op), False) |
45 | 46 | return False, None |
46 | 47 |
|
47 | | -def evaluate(code): |
| 48 | +def evaluate(code, config_json): |
| 49 | + print("worker.py: Entering evaluate function.") |
| 50 | + |
| 51 | + # --- PARSE THE JSON STRING --- |
| 52 | + config = None |
| 53 | + try: |
| 54 | + # Parse the JSON string back into a Python dictionary |
| 55 | + config = json.loads(config_json) |
| 56 | + print("worker.py: Successfully parsed challenge data JSON.") |
| 57 | + except json.JSONDecodeError as e: |
| 58 | + print(f"worker.py: Failed to decode challenge data JSON: {e}") |
| 59 | + return f"💥 Error: Could not parse challenge data - {e}" |
| 60 | + except Exception as e: |
| 61 | + print(f"worker.py: Unexpected error parsing challenge data: {e}") |
| 62 | + return f"💥 Unexpected error with challenge data: {e}" |
| 63 | + |
| 64 | + |
| 65 | + |
| 66 | + |
| 67 | + |
48 | 68 | code = code.replace("\t", " ") |
49 | 69 | namespace = {} |
50 | 70 | try: |
51 | 71 | exec(code, namespace) |
52 | 72 | except Exception as e: |
53 | 73 | return f"💥 Code failed to compile:\n{e}" |
54 | 74 |
|
55 | | - if challenge("function_name") not in namespace: |
56 | | - return f"💥 {challenge("function_name")} function not defined" |
| 75 | + if config["function_name"] not in namespace: |
| 76 | + return f"💥 {config["function_name"]} function not defined" |
57 | 77 |
|
58 | | - rule_violation, symbol = check_rules(code) |
| 78 | + rule_violation, symbol = check_rules(code, config) |
59 | 79 | if rule_violation: |
60 | 80 | return f"💥 Your solution cannot use the {symbol} operator!" |
61 | 81 |
|
62 | | - tests = challenge("test_cases") |
| 82 | + tests = config["test_cases"] |
63 | 83 |
|
64 | 84 | results = [] |
65 | 85 | for test in tests: |
66 | 86 | try: |
67 | 87 | exec(code, namespace) |
68 | | - if challenge("function_name") not in namespace: |
69 | | - results.append(f"error: '{challenge("function_name")}' function not defined") |
| 88 | + if config["function_name"] not in namespace: |
| 89 | + results.append(f"error: '{config["function_name"]}' function not defined") |
70 | 90 | continue |
71 | | - results.append(namespace[challenge("function_name")](test[0], test[1])) |
| 91 | + results.append(namespace[config["function_name"]](test[0], test[1])) |
72 | 92 | except Exception as e: |
73 | 93 | results.append( f"error: {e}") |
74 | 94 |
|
|
0 commit comments