Great Oak Meals Scheduling
Used by Great Oak Cohousing Association to schedule common meals over a several
month season. This comprises both a survey for workers to fill out, as well as
an auto-allocation algorithm looking for the best fit.
Structural Diagram in diagrams.net
Terms:
- assignment - a collection of meals assigned to a person as a block
- example: head cook - 2 meals per season
- meal - an event where someone works to cook or clean for a single date
- example: Wednesday, July 1st, 2016 at 6:15pm
- shift - an instance of a type of worker at a given meal
- this one has some ambiguous meaning, so I try not to use it
- there were 416 shifts assigned for the summer 2017 season
- example: John, assistant cook, Wednesday, July 1st, 2016 at 6:15pm
Types of meal-days and number of shifts per job:
- weekday meals (Mondays, Tuesdays, and Wednesdays)
- 1 head cook
- 2 asst cooks
- 3 cleaners
- 1 table setter (sometimes)
- Sunday meals
- 1 head cook
- 2 asst cooks
- 3 cleaners
- 1 table setter (sometimes)
- Meeting night meals (Meeting nights are the 1st Wednesday and the 3rd Monday)
- 1 orderer (head cook)
- 1 cleaner
Exceptions
We don't schedule meals on holidays, and sometimes the day before / after, consider these dates each season. Currently skipped dates:
- Jan 1st
- Easter Sunday
- 4th of July
- Memorial Day (Sunday & Monday)
- Labor Day (Sunday & Monday)
- Halloween
- Christmas Eve & Christmas
- Thanksgiving
- Sunday following Thanksgiving
- New Years Eve
Outline of duties for each season
- between work seasons
- count number of assignments for upcoming season
- setup the availability survey
- remind participants who haven't submitted their survey yet
- close the survey & do assignments
- enter the schedule into Gather
- send email publicizing that the schedule is ready
- resolve any issues with schedule
Details of Duties for each season:
- between work seasons
- work on fixing bugs
- adding / polishing features
- making changes based on work system changes
- deal with hosting headaches
- note: lately I haven't had much time to do this since we lowered the # of hours to 2/month (8 per season), and things have been "good enough"
- count number of assignments for upcoming season
- need to figure out how many of each meal type is required for the upcoming season to determine how many shifts we'll need for each type of work.
- round up to nearest "full assignment"
- the math doesn't always work out cleanly
- don't want to overly burden work committee with half shifts
- a touch of slack tends to be very helpful for scheduling
- the fractional hours lost don't matter much, as the work assignments are never completely uniform
- send report of numbers to the meals committee before the work survey begins
- (after work survey) setup the scheduling availability survey
- grab work assignments file from the work survey webserver, and put into proper place
- update deadline for closing of survey
- confirm the dates look correct in the survey
- make any last-minute changes to staffing
- swaps from current season into future
- any volunteers for shifts work was unable to fill
- get the new job IDs for the season
- test that system is working
- setup routine backups
- notify participants that the survey has started
- remind participants who haven't submitted their survey yet
- a few times during the week or so
- it actually helps me to have a few non-responders, because they can be scheduled anywhere
- close the survey & do assignments
- commit changes (so that we could come back to this state)
- run the auto-assignment process
- the algorithm essentially looks like this:
- Examine each of the job types
- example: weekday head cook
- For each job, get the list of dates where a shift would be assigned. Example for summer season meeting night orderer:
- 5/3/2017
- 5/15/2017
- 6/7/2017
- 6/19/2017
- 7/5/2017
- 7/17/2017
- 8/2/2017
- 8/21/2017
- Sort (from lowest to highest) this list of dates based on the number of people who can work that date, so that we're working on the hardest to fill date first.
- example: 7/17/2017
- Take the list of workers who are assigned to work that job type, and assign each one an arbitrary number of points. Various things factor into this point score:
- skip if worker is fully assigned for this job type
- skip if worker said "conflict" for this shift-date
- skip if worker has already been assigned this shift already
- remember there are multiple asst cooks and cleaner shifts per meal
- check "clean after cook" - if they've already been assigned the "other half" of this meal and they want to clean after cooking
- example: current job being examined is assistant cook, and they already have a cleaning shift for that date, do they have that preference checked?
- their availability score, this depends on how many shifts they've been assigned, and how "available" their schedule is.
- examples:
- Wanda should clean 4 meals, and is available to work 21 dates
- James should clean for 8 meals, and is available to work 9 dates
- James would get a higher score for this date
- If this is a group-clean job (not a meeting night cleaner or cook), and they're named as a preferred hobarter, and no other preferred hobarter is assigned already
- check to see if other people who are already assigned to work this half of meal have marked this worker with a
- prefer to work with
- avoid working with
- check to see if the current worker has a preference with anyone else who has already been assigned
- prefer to work with
- avoid working with
- do they already have "adjacent" dates assigned
- this is avoid assigning someone to work 2 or 3 days in a row, to space them out
- Add up the points for each worker, sort and assign the shift
- Display the proposed schedule
- fill in the "holes"
- my code isn't perfect, so there are often a number of shifts which haven't been filled. Usually because it gives up if there are too many constraints.
- generate a report of which workers weren't fully assigned
- try to fit them into the holes, which usually requires making some trades
- for a given hole, look at the survey preferences to see which people can work that day
- for a worker who isn't fully-assigned (John), either stick them into that slot, or look for someone who can work that day (Betty), find a different day when Betty is assigned, confirm that John can work that day, and do the trade.
- sometimes this can be a complicated 3-way (triangle trade)
- If the hole is not fillable (this happens sometimes with the meeting night orderers), then contact meals & work to explain the issue and ask for help
- read the requests & comments and make sure the schedule fulfills people's special requests as much as possible
- don't go down deep rabbit holes
- do trades when needed
- sometimes this involves doing a lot of trades by hand in order to fulfill a request for mega-cook, since I haven't written the functionality to do this yet.
- confirm that no table setters have been assigned to also work as a cook that day
- (this is a manual workaround for a lack of functionality)
- run an automated validation check to catch any other problems
- manually confirm once more that after the trades not many of the requests remain unfulfilled
- enter the schedule into Gather
- since Tom & I haven't spent the time to support uploads yet, I've been adding this manually, doing the clickety-click for every shift
- this can be about 30 or so clicks plus some typing for entering names for each meal
- need to pay attention to make sure that mistakes aren't made (e.g. Kate vs Katie)
- alter the details for meeting night meals
- earlier time
- only GO, no SW or TS
- resolve any reservation conflicts - usually this is done by modifying their reservation and notifying that person
- I would love to have this be an automated process BUT:
- usernames between Dale's work survey and Gather are different
- we could use normalized usernames
- we could use single-sign-on
- need to write an import routine into Gather
- send email publicizing that the schedule is ready
- resolve any issues with schedule
- if I made a mistake, then arrange trades and send out emails asking for swaps
- Once published, people are likely to have made copies of their schedule
- Also, the respondent's availability survey results are likely a week or more old, so their plans may have changed
- if the mistake is not mine, then point out the survey report so that they can have an easier, more targeted time finding a swap for themselves
Historical reference
FALL 2017 common meals
- 40 Weekday meals
- 15 Sunday meals
- 8 Meeting night meals
Meal shifts we request:
- Weekday head cook (20 instances 2 HRS/Month)
- Weekday meal asst cook (40 instances 1 HRS/Month)
- Weekday Meal Cleaner (30 instances 1.5 HRS/Month)
- Weekday table setter (10 instances 0.5 HRS/Month)
- Meeting night takeout orderer (4 instances 0.5 HRS/Month)
- Meeting night cleaner (4 instances 0.75 HRS/Month)
- Sunday head cook (8 instances 2 HRS/Month)
- Sunday meal asst cook (15 instances 1 HRS/Month)
- Sunday Meal Cleaner (12 instances 1.5 HRS/Month)
Formula for calculating the number of shifts:
- Let M = number of meals we're trying to cover (for Sundays, 12)
- Let W = number of workers of this type assigned to each meal (e.g. 3 cleaners)
- Let S = number of meals per assigned shift (2 for cooks, 4 for cleaners)
- The formula would then be: (M * W) / S