Day 21 of the Anvil Advent Calendar

Build a web app every day until Christmas, with nothing but Python!

Cooking in parallel

I don’t think anyone who knows me would accuse me of being an excellent chef, but I have a talent for ruining even simple meals by messing up the timing. If you have the same problem, then today I have just the app for you: A recipe scheduler with live timing display.

Who wants to be in the kitchen when they could be keeping themselves occupied with some recursive critical path analysis? Here goes!

So… What time should I start if I want to be done by 3:30pm?

So… What time should I start if I want to be done by 3:30pm?

This app stores recipes (and the tasks within them) in a couple of linked Data Tables. Each task has a duration and links to the tasks it depends on, and each recipe has a link to its final task.

The dependency graph above, this time in relational-database-form

The dependency graph above, this time in relational-database-form

At its core, the app is really a simple recursive algorithm to walk the recipe backwards from the last task, working out the latest time that each preceding task must start in order to serve up on time:

# Keep a dict of task -> latest_start_time
latest_starts = {}

# Recursively walk the tasks in the selected recipe, calculating the latest time each can start
def walk(task, latest_start):
  
  this_task_latest_start = latest_start - timedelta(minutes=task['duration_mins'])
  latest_starts[task] = min(this_task_latest_start, latest_starts.get(task, this_task_latest_start))
  
  for t in task['depends_on'] or []:
    walk(t, latest_starts[task])
    
walk(self.recipe['final_task'], self.finish_time.date)

Give the app a try yourself! You can customise the recipe by editing the Data Tables directly in Anvil.

I might keep quiet about this one. Now I have no excuse for messing things up…


Give the Gift of Python

Share this post: