Level 1 Fix the dasher picker
The starter file has a DasherPicker that a teammate wrote. It hands out orders to dashers and has several bugs. Read the whole class before you change anything, reproduce each bug with a tiny example, then fix it. You don't have to rewrite it from scratch.
Here's what it's meant to do.
Dashers sit in a list of slots. A dict maps each dasher to their slot index, so every operation is O(1).
DasherPicker(seed=None): creates an empty picker. Two pickers never share state. It also creates onerandom.Random(seed)that later calls reuse.add(dasher) -> bool: puts a new dasher in a new slot at the end and returnsTrue. If the dasher is already present, returnsFalse.remove(dasher) -> bool: returnsFalseif the dasher is absent. Otherwise it moves the last slot's dasher into the removed dasher's slot, shrinks the list by one and returnsTrue. The moved dasher's index must be updated. Removing the dasher who is already in the last slot just shrinks the list.pick() -> str | None: round robin. ReturnsNoneif there are no dashers. Otherwise, if the cursor is past the end of the list, it wraps to0. It then returns the dasher at the cursor and moves the cursor forward one slot. Removals don't touch the cursor. The first pick returns slot 0.pick_random() -> str | None: returnsNonewhen empty. Otherwise it returnsslots[r.randrange(len(slots))], whereris the picker's singleRandom. That is exactly onerandrangecall per pick.dashers() -> list[str]: a copy of the slots in order.len(picker)anddasher in pickerwork too.
p = DasherPicker()
for d in ["ann", "bo", "cy"]:
p.add(d)
[p.pick() for _ in range(4)] # ["ann", "bo", "cy", "ann"]
p.remove("ann") # "cy" moves into slot 0
p.dashers() # ["cy", "bo"]
p.pick() # "bo" (cursor was at slot 1)