Paper 2 Validation Testing Answers

These answers correspond to Paper 2 Validation Testing Drills.

Verification note: every Python code block in this answer file has been executed locally.

Answer 1: Range Validation

Model answer:

def valid_mark(mark):
    return mark >= 0 and mark <= 100
 
 
print(valid_mark(-1))
print(valid_mark(0))
print(valid_mark(100))
print(valid_mark(101))

Expected output:

False
True
True
False

Mark points:

  • defines valid_mark(mark);
  • checks the lower bound;
  • checks the upper bound;
  • includes both extreme values as valid;
  • produces the expected outputs.

Common weak answer:

  • using strict inequalities, which reject valid boundary marks.

Answer 2: Presence Validation

Model answer:

def present(text):
    return text.strip() != ""
 
 
print(present("Amy"))
print(present(""))
print(present("   "))

Expected output:

True
False
False

Mark points:

  • strips or otherwise ignores spaces;
  • rejects empty strings;
  • rejects spaces-only strings;
  • accepts a string containing a non-space character.

Common weak answer:

  • using text != "", which incorrectly accepts " ".

Answer 3: Format Validation

Model answer:

def valid_code(code):
    if len(code) != 6:
        return False
    if not code[0:2].isalpha():
        return False
    if not code[0:2].isupper():
        return False
    if not code[2:6].isdigit():
        return False
    return True
 
 
print(valid_code("AB1234"))
print(valid_code("A12345"))
print(valid_code("Ab1234"))
print(valid_code("CD12E4"))

Expected output:

True
False
False
False

Mark points:

  • checks exact length 6;
  • checks the first two characters;
  • requires letters for the first two characters;
  • requires uppercase for the first two characters;
  • checks the last four characters;
  • requires digits for the last four characters;
  • returns Boolean values;
  • matches all expected outputs.

Common weak answer:

  • checking only code.isalnum(). That does not enforce the required positions.

Answer 4: Length Check

Model answer:

def valid_password_length(password):
    return len(password) >= 8 and len(password) <= 12
 
 
print(valid_password_length("abc1234"))
print(valid_password_length("abc12345"))
print(valid_password_length("abcdefghijkl"))
print(valid_password_length("abcdefghijklm"))

Expected output:

False
True
True
False

Mark points:

  • checks the minimum length;
  • checks the maximum length;
  • includes length 8;
  • includes length 12.

Common weak answer:

  • checking only the minimum length and accepting overly long passwords when the task specifies a maximum.

Answer 5: Check Digit

Model answer:

def valid_check_digit(code):
    if len(code) != 4:
        return False
    if not code.isdigit():
        return False
 
    total = int(code[0]) + int(code[1]) + int(code[2])
    expected = total % 10
    supplied = int(code[3])
    return supplied == expected
 
 
print(valid_check_digit("2462"))
print(valid_check_digit("2463"))
print(valid_check_digit("24A2"))

Expected output:

True
False
False

Mark points:

  • checks exact length;
  • checks all characters are digits;
  • extracts the first three digits;
  • converts digit characters to integers;
  • sums the first three digits;
  • applies modulo 10;
  • extracts the supplied check digit;
  • compares expected and supplied digits;
  • returns False for a wrong check digit;
  • returns False for non-digit input.

Common weak answer:

  • adding character strings directly, which concatenates text instead of adding numbers.

Answer 6: Test Cases

Model answer:

def valid_age(age):
    return age >= 13 and age <= 18
 
 
def run_age_tests():
    ages = [12, 13, 15, 18, 19]
    results = []
    for age in ages:
        results.append((age, valid_age(age)))
    return results
 
 
print(run_age_tests())

Expected output:

[(12, False), (13, True), (15, True), (18, True), (19, False)]

Mark points:

  • implements the valid age range;
  • includes below-range abnormal data;
  • includes lower boundary data;
  • includes normal data;
  • includes upper boundary data;
  • includes above-range abnormal data.

Common weak answer:

  • testing only valid ages. Abnormal and boundary cases are needed to expose validation errors.

Answer 7: Debug Runtime Error

Model answer:

def safe_int(text):
    if text.strip() == "":
        return None
    try:
        return int(text)
    except ValueError:
        return None
 
 
print(safe_int("42"))
print(safe_int(""))
print(safe_int("   "))
print(safe_int("abc"))

Expected output:

42
None
None
None

Mark points:

  • checks for blank input;
  • strips spaces before the blank check;
  • attempts integer conversion for non-blank input;
  • catches invalid integer text;
  • returns None instead of crashing;
  • returns the integer for valid input.

Common weak answer:

  • calling int(text) without catching ValueError, which will crash for blank or non-integer text. A blank check is useful for clearer validation, but conversion may also be attempted inside try and handled with except ValueError.

Answer 8: Debug Logic Error

Model answer:

def passed(mark):
    return mark >= 50
 
 
print(passed(49))
print(passed(50))
print(passed(51))

Expected output:

False
True
True

Mark points:

  • uses >= rather than >;
  • returns False for 49;
  • returns True for boundary value 50;
  • returns True for value above boundary;
  • produces all expected outputs.

Common weak answer:

  • changing the threshold to 49, which may pass the given tests but no longer represents the rule clearly.

Answer 9: Assertions

Model answer:

def valid_mark(mark):
    return mark >= 0 and mark <= 100
 
 
def assert_valid_mark_tests():
    assert valid_mark(-1) is False
    assert valid_mark(0) is True
    assert valid_mark(100) is True
    assert valid_mark(101) is False
    return "ALL TESTS PASSED"
 
 
print(assert_valid_mark_tests())

Expected output:

ALL TESTS PASSED

Mark points:

  • asserts a below-range invalid case;
  • asserts the lower boundary;
  • asserts the upper boundary;
  • asserts an above-range invalid case.

Common weak answer:

  • writing assert valid_mark(0) only. One passing assertion is not enough coverage.

Answer 10: Integrated Validation Loop

Model answer:

def parse_mark(text):
    if text.strip() == "":
        return None
 
    try:
        mark = int(text)
    except ValueError:
        return None
 
    if mark < 0 or mark > 100:
        return None
 
    return mark
 
 
def read_valid_mark():
    mark = parse_mark(input("Enter mark: "))
 
    while mark is None:
        print("Invalid mark")
        mark = parse_mark(input("Enter mark: "))
 
    return mark
 
 
print(parse_mark(""))
print(parse_mark("abc"))
print(parse_mark("-1"))
print(parse_mark("0"))
print(parse_mark("100"))
print(parse_mark("101"))

Expected output:

None
None
None
0
100
None

Mark points:

  • handles blank or non-integer input without crashing;
  • catches ValueError specifically;
  • rejects marks below 0 and above 100;
  • accepts both extreme values 0 and 100;
  • repeats input until a valid mark is entered;
  • displays an error message for invalid input;
  • returns the accepted integer;
  • includes meaningful helper tests.

Common weak answer:

  • using a bare except, which may hide unrelated programming errors.