Robust boundaries and honest authentication models
By UK GCSE Computer Science · independent study · myAudience

Original AI-generated teaching raster via built-in image_gen; author inspected 2026-10-04. · Generated project artwork; no copied exam or publisher illustration. Independent rights/publication review pending.
Robust boundaries and honest authentication models
Robust programming anticipates valid, invalid and adversarial inputs instead of assuming the caller behaves. Our fictional booking accepts an ASCII decimal whole number from 1 through 10. Validation checks shape, conversion and range; verification would check whether it is the intended booking quantity. Entry skills are parsing and boundary decisions. A length or range check cannot prove that a measurement is true. Conversely a syntactically valid password does not prove identity; authentication compares evidence of identity against an agreed mechanism.
Normal data such as "4" samples typical operation. Boundary data "0","1","10","11" probes either side of the inclusive limits as specified by an awarding body. Erroneous data includes empty text, "two", "1.5" and an unsupported type. Predict whether each should produce a value or a structured failure before running it. This program raises ValueError for invalid text and TypeError for a non-string input. A UI can catch those at the boundary and display a helpful explanation; silently converting everything to a string can conceal misuse by another module.
Syntax errors prevent the code being parsed, while logic errors can run and return a wrong result. A mistaken upper check value > 9 rejects the valid boundary 10, and a mistaken and between lower and upper rejection conditions rejects nothing. A test that asserts only quantity("4") == 4 cannot discriminate these errors. Refinement means changing the implementation in response to a failing requirement or test, then rerunning previous tests to check that the repair did not break other behaviour. Tests do not replace a clear specification of expected failure.
requires a simple username/password authentication routine and permits plain text in that assessment model. The example therefore compares two explicitly fictional strings passed as parameters; no real secret is present or requested. It is intentionally not an account implementation. In a real system, password storage, rate limits, access authorisation, safe recovery and transport protection are separate responsibilities. Authentication asks who is making a request; authorisation asks whether that identity may access a particular object. A successful toy comparison must not be interpreted as permission to view any record.
Security and ethics intersect at the boundary. Keeping detailed failed passwords in a log creates a privacy risk, and revealing whether a username exists can leak information. A fictional Boolean result is enough for the lesson. The generated logic visual supports mandatory conditions: both matching name and matching password are needed. Do not replace AND with OR to make a test “pass”. The demanding transfer adds retry state and a finite attempt budget; it asks you to reason about side effects and privacy as well as correctness.
Runnable original Python 3 example (also saved verbatim in examples for CLI execution):
```python
def quantity(text):
"""Parse ASCII booking text in inclusive range 1..10."""
if not isinstance(text, str):
raise TypeError("text required")
if not text or any(ch not in "0123456789" for ch in text):
raise ValueError("whole ASCII digits required")
value = int(text)
if not 1 <= value <= 10:
raise ValueError("quantity outside 1..10")
return value
def toy_auth(name, password, expected_name, expected_password):
"""Fictional plain-text assessment model; no real account or secret."""
return name == expected_name and password == expected_password
assert quantity("10") == 10
assert toy_auth("demo-learner", "fictional-word", "demo-learner", "fictional-word")
assert not toy_auth("other", "fictional-word", "demo-learner", "fictional-word")
for bad in ("0", "11", "", "two", "1.5"):
try:
quantity(bad)
except ValueError:
pass
else:
raise AssertionError(bad)
```
Worked example: Explain why "10" and "11" are more useful together than a second typical valid value when testing an upper bound.
10 must be accepted and 11 rejected.
An off-by-one upper bound of 9 fails the first case; a bound of 11 fails the second.
A typical value such as 4 satisfies all three implementations and cannot locate the boundary error.
Answer: The pair distinguishes the specified inclusive limit from either neighbouring mistaken limit.
Check your understanding: Transfer: a routine permits at most three fictional attempts and stops immediately on success. For failures F,F then success S followed by F, how many comparisons occur? Specify the empty-input behaviour and a test for failure after three attempts.
Answer: Three comparisons occur; the fourth item is never examined. Empty input returns failure with zero comparisons. For F,F,F,S, return failure after exactly three comparisons and ignore S. Use a counter or a finite slice and stop on success.
Why: The limit is a control-flow requirement, not merely an output requirement. A routine that computes all comparisons then returns any(success) violates the attempt budget. Do not log attempted passwords; a count and generic outcome are enough for this fictional test.