Skip to content
Putting It All Together
step 1/4

Reading — step 1 of 4

Learn

~3 min readReal-World Python

Putting It All Together

You've learned classes, dunder methods, generators, decorators, regex, and JSON as separate tools. Real programs are where they meet. The most common shape for a real program is the command loop: read a command, parse it, dispatch to the right handler, mutate some state, print a result. That's what a shell is, what a database CLI is, and what this lesson's inventory manager is.

The architecture

Three layers, cleanly separated:

  1. State + rules — a class that owns the data and enforces the invariants (chapter 1).
  2. Dispatch — mapping command names to handlers instead of growing an if/elif ladder forever.
  3. The I/O loop — reading stdin until EOF and printing exact output.
python

Look closely at remove: it checks both failure cases before touching the data. Validate first, mutate last — a failed remove must leave the quantity exactly as it was. Guarding invariants like this is the whole reason the state lives inside a class instead of a bare dict scattered through the script.

Reading commands until EOF

python

for line in sys.stdin is the EOF-safe idiom — the loop simply ends when input ends. A while True: input() loop raises EOFError at the end and needs a try/except to avoid crashing after the last command.

If the if/elif ladder bothers you, dispatch through a dict — functions are first-class values:

python

Exact output is the contract

Graders — and every real program that consumes your output — compare text byte-for-byte. error: not found is not Error: Not Found. apple: 5 has a colon and a space. An empty inventory prints the single word empty, not nothing. When output is a protocol, formatting is correctness.

Where do the other tools fit? A production version of this program would persist self.items with json.dump on exit and json.load on startup, validate item names with a regex, and wrap each handler in a logging decorator. The architecture wouldn't change — that is the payoff of separating state, dispatch, and I/O.

Your exercise

Implement add, remove, search, and list exactly as specified. The mistakes the grader will catch: (1) remove on an item that was never added must print error: not found — the visible test issues a remove before any add, so unguarded self.items[name] access crashes; (2) a remove larger than the stock must print error: insufficient and leave the count unchanged — the hidden test runs add apple 3, remove apple 5, then expects search apple to print 3; (3) list on an empty inventory must print empty; (4) list lines are alphabetically sorted and formatted name: quantity with a colon and a space.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…