Defensive design
Anticipating misuse, authentication, input validation and maintainable code.
Learning Objectives
- 1Understand the issues a programmer should consider to cater for all likely input values
- 2Understand how to deal with invalid data in a program
- 3Understand authentication and design simple authentication
- 4Design input validation for a given scenario
- 5Understand why commenting and other maintainability techniques are useful
What is defensive design?
Authentication
stored_password = "Sc1ence123"
entered_password = input("Enter your password: ")
if entered_password == stored_password:
print("Access granted")
else:
print("Access denied")storedPassword = "Sc1ence123"
enteredPassword = input("Enter your password: ")
if enteredPassword == storedPassword then
print("Access granted")
else
print("Access denied")
endifInput validation
total >= 10 AND total <= 20, not total >= 10 AND <= 20.name = input("Enter your name: ")
if name == "":
print("Name cannot be blank")
age = int(input("Enter your age: "))
if age < 0 or age > 120:
print("Age out of range")
password = input("Enter a password (min 8 characters): ")
if len(password) < 8:
print("Password too short")name = input("Enter your name: ")
if name == "" then
print("Name cannot be blank")
endif
age = int(input("Enter your age: "))
if age < 0 OR age > 120 then
print("Age out of range")
endif
password = input("Enter a password (min 8 characters): ")
if password.length < 8 then
print("Password too short")
endifMaintainability: sub-programs and naming conventions
density rather than num3, so anyone reading the code can follow what it does without extra explanation.# Poor: unclear what each variable represents
num1 = float(input("Enter the mass: "))
num2 = float(input("Enter the volume: "))
num3 = num1 / num2
# Clear: purpose of each variable is obvious
mass = float(input("Enter the mass: "))
volume = float(input("Enter the volume: "))
density = mass / volume// Poor: unclear what each variable represents
num1 = real(input("Enter the mass: "))
num2 = real(input("Enter the volume: "))
num3 = num1 / num2
// Clear: purpose of each variable is obvious
mass = real(input("Enter the mass: "))
volume = real(input("Enter the volume: "))
density = mass / volumeMaintainability: indentation and commenting
#, in OCR's Exam Reference Language with //.def add_numbers(num1, num2):
total = num1 + num2 # Adds the two numbers together
return total # Sends the result back to the callerfunction addNumbers(num1, num2)
total = num1 + num2 // Adds the two numbers together
return total // Sends the result back to the caller
endfunctionExam Phrasing: Use These Exact Phrases
- ✓Defensive design means anticipating misuse and designing a program to handle it
- ✓Authentication confirms the identity of a user, usually with a username and password
- ✓Validation checks that data is an acceptable format or value before it is processed
- ✓Maintainable code is easy to read, understand and modify, using sub-programs, sensible naming, indentation and comments
- 💡Don't confuse maintainability with testing, they are two separate, specifically distinguished topics in past examiner reports.
- 💡When suggesting a maintainability improvement, refer to the specific code given in the question, not a generic list of techniques.
- 💡If code shown in a question is already well-indented, don't suggest "add indentation" as an improvement, it must be a genuine improvement to what's shown.
- 💡A validation example (e.g. a specific range check) can also count as an example of anticipating misuse, these mark points often overlap.
- 💡In a range check condition, always repeat the variable in both parts, e.g. total >= 10 AND total <= 20.
Wrong:
Leaving the quotation marks off a string, e.g. if answer == yes then
Right:
Put quotation marks around string values, e.g. if answer == "yes" then
Why it matters: OCR examiners flagged this. Without the quotes, yes reads as a variable name rather than a piece of text, so the comparison does something quite different.
Wrong:
Maintainability and testing are the same thing
Right:
Maintainability is about how easy code is to read and modify; testing is about checking a program works correctly
Why it matters: Examiners specifically noted that candidates who did less well on this paper confused maintainability with testing.
Wrong:
if total >= 10 AND <= 20 then
Right:
if total >= 10 AND total <= 20 then
Why it matters: The second part of the condition must reference the variable again, otherwise it has nothing to compare against.
Wrong:
Suggesting "add comments" or "add indentation" as an improvement when code is already well-commented/indented
Right:
Only suggest an improvement that genuinely applies to the specific code shown
Why it matters: Examiners do not credit improvements that have clearly already been done in the code given.
Question:
A program asks the user to enter their age, and should only accept ages from 0 to 120. Write validation code to check the age is within this range, and reject it otherwise. [3]
age = int(input("Enter your age: "))
if age < 0 or age > 120:
print("Invalid age")
else:
print("Age accepted")age = int(input("Enter your age: "))
if age < 0 OR age > 120 then
print("Invalid age")
else
print("Age accepted")
endif💡 Attempt this before revealing the answer, practice makes perfect!
Model Answer:
The program takes the age as input and casts it to an integer, then checks whether it is less than 0 or greater than 120 using a range check. If either condition is true, the age is rejected as out of range; otherwise, it is accepted.
Mark Scheme:
- 1Correctly casts the input to an integer
- 2Correctly checks age is less than 0 OR greater than 120 (both boundaries referenced correctly)
- 3Correctly rejects/flags the value when out of range
Tap a card to flip it. Use the arrow keys to move and space to flip.
Exam-style questions. Have a go, then reveal the mark scheme to check your answer.
1.Explain the difference between authentication and validation.
[2]2.A registration form requires a password of at least 8 characters. Write code to validate this, rejecting passwords that are too short.
[2]3.Describe two maintainability techniques a programmer could use, other than commenting.
[2]4.A student describes an algorithm as "not maintainable because it doesn't work correctly for large inputs". Explain why this is an incorrect use of the term "maintainable".
[2]5.A booking system asks for the number of tickets, which must be between 1 and 4 inclusive. Write validation code to check this, and explain why both boundary values (1 and 4) must be included in your check.
[4]tickets = int(input("Enter number of tickets: "))
if tickets >= 1 and tickets <= 4:
print("Accepted")
else:
print("Invalid number of tickets")tickets = int(input("Enter number of tickets: "))
if tickets >= 1 AND tickets <= 4 then
print("Accepted")
else
print("Invalid number of tickets")
endif6.Explain how a programmer could make a login system robust, referring to input validation, authentication and maintainability.
[6]The examiners' reports are the most useful and least read of the three: they say what candidates actually got wrong each year. All files are hosted by OCR.
Past-paper questions grouped by topic
The same OCR questions, sorted by topic rather than by year (via Physics & Maths Tutor).
Candidates who did less well on the paper commonly confused maintainability of a program with testing, these are two distinct required concepts (2.3.1 and 2.3.2) and should not be conflated in answers.
When describing how defensive design could be used in a given scenario, examiners noted that many mark scheme points crossed over, for example a specific validation example was accepted as a sensible expansion of 'anticipating misuse'. Candidates needed to both name a technique and describe how it was used, generically or with a specific example, to gain full marks.
A recurring misconception across multiple questions: when a selection statement needs to check that a value is between two bounds, both parts of the condition must reference the variable, e.g. if total >= 10 AND total <= 20 then. Writing if total >= 10 AND <= 20 then is a syntax error, since the second part has nothing to compare against.