Python input reads a text line, while print writes formatted text; neither establishes the domain meaning of that text.
Python input and output: separate parsing from terminal I/O
Operation contract
The receipt parser receives a stream rather than reading the process terminal directly. It accepts one newline-terminated ASCII quantity with at most two digits and returns an integer in the declared range. The output stream belongs to the caller, so the operation writes its accepted quantity without closing either stream. In-memory streams let the same operation be tested without an interactive prompt.
Failure and ownership boundary
EOF and a blank line differ. Readline returns an empty string at EOF but returns a newline for an empty entered line. A bounded read detects oversized or unterminated input instead of consuming an arbitrary line. This protocol intentionally rejects surrounding spaces and signs; accepting those would be a different wire contract. Python type conversion: parsing success is not field validity and Python input exercise: accept an explicit integer grammar keep the parser separate from user-interface behavior.
Working program
from io import StringIO
import re
def read_quantity(source, output):
line = source.readline(5)
if line == "":
raise EOFError("quantity input ended")
if re.fullmatch(r"[0-9]{1,2}\n", line) is None:
raise ValueError("quantity line rejected")
quantity = int(line[:-1])
if not 1 <= quantity <= 20:
raise ValueError("quantity range rejected")
print(f"accepted quantity: {quantity}", file=output)
return quantity
source, output = StringIO("3\n"), StringIO()
print(read_quantity(source, output))
print(output.getvalue().strip())
for text in ("", "\n", "123456\n"):
try:
read_quantity(StringIO(text), StringIO())
except (EOFError, ValueError) as failure:
print(type(failure).__name__)Output
3
accepted quantity: 3
EOFError
ValueError
ValueErrorCosts and limits
The five-character read bounds this operation’s text work. It does not drain rejected input for a later prompt; a caller that continues on the same terminal must choose a recovery policy. Stream reception and blocking latency are external to this parser.
Common Mistakes
- EOF is not a blank entered line.
- Do not close a caller-owned stream after writing one result.
Connected lessons
Python type conversion: parsing success is not field validity, Python input exercise: accept an explicit integer grammar, Pytest fixtures: isolated files and parameterized rejection tests.
