Paws & Play: Daycare Check-In
EasyAI-assisted coding · AI-Assisted Debugging
Paws & Play: Daycare Check-In
You've joined the small team behind the front-desk system of Paws & Play, a dog daycare. The system decides whether a dog may come in, which play room it goes to, and what the owner pays at pickup. Three tickets are open: front desk is reporting wrong answers, billing wants households to be priced fairly, and the behaviour team wants reactive dogs handled safely. All prices are integer cents.
Codebase
| File | What it does |
|---|---|
daycare/api.py | run(operations) entry point and the Dispatcher that validates and routes each operation |
daycare/service.py | Daycare: registering dogs, vaccinations, check-in, check-out, room status |
daycare/rooms.py | RoomBoard: which dogs are in which room, and which room a new dog gets |
daycare/vaccines.py | VaccineBook: vaccination expiry records and the "is this dog covered today" check |
daycare/billing.py | Day rates, late fee and the bill returned at pickup |
daycare/config.py | Rates, opening hours, room list, size units, required vaccines |
daycare/clock.py | Parsing of dates and HH:MM times |
daycare/models.py, daycare/errors.py | Records and every error message |
tests/ | Existing tests (some currently fail) |
All rates, hours, rooms and size units live in config.py; the examples below use those values.
How your code is run
run(operations: list[list]) -> list executes the operations in order against a fresh daycare and returns one result per operation. Every operation is [name, date, time, ...args]. date is a "YYYY-MM-DD" string (only the shape is checked; ISO dates compare correctly as plain strings) and time is "HH:MM" from 00:00 to 23:59. Errors are returned as "error: <message>", never raised.
| Operation | Arguments after time | Returns | Errors (checked in this order) |
|---|---|---|---|
register | dog_id, owner_id, size | true | dog exists, invalid size |
vaccinate | dog_id, vaccine, expires | true | unknown dog, unknown vaccine |
check_in | dog_id | name of the room | unknown dog, already checked in, daycare closed, vaccine <name> missing / vaccine <name> expired, no room available |
check_out | dog_id | bill (below) | unknown dog, not checked in, day mismatch |
room_status | none | {room: [dog ids]} for every room, each list in arrival order | none |
- An unknown operation name returns
"error: unknown operation". A malformed operation (not a list, fewer than three elements, bad date or time, wrong number of arguments, an id that is not a non-empty string, anexpiresthat is not aYYYY-MM-DDstring) returns"error: invalid arguments"; this is checked before anything else. sizeis"S","M"or"L". The only vaccines arerabies,dhppandbordetella. Every dog needs all three.- A vaccine is valid through its expiry date: it covers every date
<= expires.vaccinatenever shortens an existing record (a laterexpiresreplaces it, an earlier one is ignored). The first uncovered vaccine, in the orderrabies, dhpp, bordetella, is the one reported:missingif no record exists,expiredotherwise. - Check-in is allowed from
07:00up to but not including18:00; otherwisedaycare closed. - Rooms. Capacity is counted in size units (
S=1,M=2,L=3). Large dogs are never placed incozy. A room is *eligible* for a dog if it allows the dog's size and has enough free units. The dog goes to the eligible room that would have the fewest free units left after placing it; on a tie, the room listed first inconfig.py. If no room is eligible:no room availableand the dog is not checked in. - A dog must be picked up on the day it checked in (
day mismatchotherwise). Pickup frees the dog's space. - Bill returned by
check_out:{"dogs": [[dog_id, charge]], "late_fee": n, "total": n}. A pickup at or before13:00is a half day, later pickups are a full day (rates inconfig.py). The late fee is500for every *started* 15 minutes after18:00: nothing at18:00,500for18:01through18:15,1000for18:16, and so on.totalis the sum of all charges plus the late fee.
Worked example
[["register", "2025-03-10", "07:00", "rex", "o1", "M"],
["vaccinate", "2025-03-10", "07:00", "rex", "rabies", "2025-03-10"],
["vaccinate", "2025-03-10", "07:00", "rex", "dhpp", "2026-01-01"],
["vaccinate", "2025-03-10", "07:00", "rex", "bordetella", "2025-09-01"],
["check_in", "2025-03-10", "08:05", "rex"],
["check_out", "2025-03-10", "18:20", "rex"]]returns
[true, true, true, true, "cozy", {"dogs": [["rex", 3650]], "late_fee": 1000, "total": 4650}]Rex's rabies certificate runs out on the day he visits, which still counts. He is picked up 20 minutes late, which is two started quarter-hours.
Part 1: Fix three front-desk defects (SUP-410, SUP-418, SUP-425)
Goal: make check-in, rooms and billing follow the rules above. Reports from the front desk:
- "We turned Max away on the exact day his rabies certificate expires."
- "A family picking up at 18:05 paid no late fee, and at 18:20 they were charged only one block."
- "Once a few medium dogs go home, the cozy room still says it is full, so new small and medium dogs get pushed into the meadow."
Rules
- A vaccine whose
expiresequals the visit date covers that visit; the next day it does not. - The late fee counts every *started* 15-minute block after
18:00. - After pickup the room has exactly as much free capacity as before the dog arrived, whatever its size.
The failing tests in tests/test_daycare.py show the symptoms. Everything not mentioned here already works and must keep working, including the order in which check-in errors are reported.
Part 2: Household pickups (BILL-77)
Goal: an owner usually collects several dogs at once. check_out now accepts one or more dog ids and bills them as one pickup with a multi-dog discount.
["check_out", date, time, dog_id, dog_id, ...]
Rules
- All listed dogs must belong to the same owner. Dogs are validated in the listed order:
unknown dog, thennot checked in, thenday mismatchfor each dog in turn; only after every dog passes is the owner check made (different owners). Listing the same dog twice, or a non-string id, isinvalid argumentsand is checked before any of these. If any error occurs, nobody leaves and nothing changes. - Each dog's *base charge* is its half-day or full-day rate, decided once by the pickup time.
- The dog with the highest base charge pays it in full (if several are tied, the one listed first). Every other dog pays
base - base // 4(integer arithmetic; a quarter off, rounded so the customer pays the extra cent). - The late fee is charged once per pickup, not per dog, and is never discounted.
- The bill lists the dogs in the order given;
totalis the sum of their charges plus the late fee. With a single dog the bill is exactly what Part 1 produced. - All dogs in the pickup leave their rooms.
Example (all three dogs already checked in on 2025-03-10; bruno is an L, rex an M, pip an S, all owned by o1)
[["check_out", "2025-03-10", "12:30", "rex", "bruno", "pip"]]returns
[{"dogs": [["rex", 1613], ["bruno", 2500], ["pip", 1275]], "late_fee": 0, "total": 5388}]bruno has the highest half-day rate (2500) and pays it. rex: 2150 - 537 = 1613. pip: 1700 - 425 = 1275.
Part 3: Reactive dogs (BEH-31)
Goal: the behaviour team flags some dogs as *reactive*. A reactive dog must never share a room with more than two other dogs. The old rule "a room accepts a dog if the units fit" is no longer enough.
register takes an optional fourth argument after size: the dog's temperament, "calm" (default) or "reactive". Any other value is error: invalid temperament (checked after invalid size).
Rules
- A reactive dog may only be placed in a room that currently holds at most 2 other dogs (any sizes; count dogs, not units).
- While a reactive dog is in a room, no dog of any temperament may join it once it already holds 3 or more dogs, even when units are free. (So a room with a reactive dog never has more than 3 dogs, and a calm newcomer is refused a room where a reactive dog already shares with two others.)
- The existing rules still apply on top: size restrictions (
cozyhas no large dogs), unit capacity, and the tightest-fit room choice among the rooms that are eligible under all rules. Dogs already in a room are never moved. Once the reactive dog leaves, the limit stops applying to that room. - A reactive dog's charge at pickup includes a surcharge of 800, added after the household discount: the surcharge is never discounted, and it does not change which dog is the highest-charged one (that is decided by base charge alone).
- Everything from Parts 1 and 2 still holds. The late fee is still charged once per pickup.
Example (all dogs owned by different people, fully vaccinated, size S; a, b, c calm, r reactive)
[["check_in", "2025-03-10", "08:00", "a"],
["check_in", "2025-03-10", "08:01", "b"],
["check_in", "2025-03-10", "08:02", "c"],
["check_in", "2025-03-10", "08:03", "r"]]returns ["cozy", "cozy", "cozy", "meadow"]. cozy holds three dogs, which is more than two, so the reactive dog cannot go there even though units are free, and meadow is the next-best eligible room. A fourth *calm* dog arriving now still gets cozy (3 dogs, 4 of 6 units used, no reactive dog in it).
Notes
- You may use the AI assistant freely; you are expected to verify what it produces.
- Later parts must not break earlier ones; hidden tests re-check earlier behaviour.
Example 1
- Input:
- [["register","2025-03-10","07:00","rex","o1","M"],["vaccinate","2025-03-10","07:00","rex","rabies","2025-03-10"],["vaccinate","2025-03-10","07:00","rex","dhpp","2026-01-01"],["vaccinate","2025-03-10","07:00","rex","bordetella","2025-09-01"],["check_in","2025-03-10","08:05","rex"],["check_out","2025-03-10","18:20","rex"]]
- Output:
- [true,true,true,true,"cozy",{"dogs":[["rex",3650]],"late_fee":1000,"total":4650}]
- Explanation
- The rabies certificate still covers its expiry day. The pickup is 20 minutes late: two started quarter-hours, 1000 cents.
Guidelines
- Python 3 standard library only
- All money is integer cents; no floating-point prices
- Dates are "YYYY-MM-DD" strings and times are "HH:MM" strings
- Every operation returns exactly one value; errors are returned as "error: <message>" strings, never raised