Spaces:
Running
Running
File size: 1,670 Bytes
b9499ab | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | from logic import forward_mode, parse_function, reverse_mode, state_after
class UserError(Exception):
"""A mistake the student can fix; its message is shown in the UI."""
class Manager:
def __init__(self):
self._graph: dict | None = None
self._run: dict | None = None
def handle_set_function(self, args: dict) -> dict:
"""{expression}; returns the function's computational graph.
A function that doesn't parse leaves the current one and its run in place.
"""
try:
self._graph = parse_function(str(args["expression"]))
except ValueError as e:
raise UserError(str(e))
self._run = None
return self._graph
def handle_set_run(self, args: dict) -> dict:
"""{mode: "forward" | "reverse", inputs: {name: value}, seed}; seed is the input forward mode differentiates by.
Returns {steps}, the run's number of steps.
"""
self._run = None
inputs = {name: float(value) for name, value in args["inputs"].items()}
try:
if args["mode"] == "forward":
self._run = forward_mode(self._graph, inputs, args["seed"])
else:
self._run = reverse_mode(self._graph, inputs)
except ValueError as e:
raise UserError(str(e))
return {"steps": len(self._run["steps"])}
def handle_state(self, args: dict) -> dict | None:
"""The run after {iteration} steps; None past the end."""
k = int(args["iteration"])
if self._run is None or k > len(self._run["steps"]):
return None
return state_after(self._run, k)
|