Paper 2 Lab Skills Answers
These answers correspond to Paper 2 Lab Skills Drills.
Verification note: every Python code block in this answer file has been executed locally.
Answer 1: Folder Setup
Model answer:
def required_paths():
return ["app.py", "templates/books.html", "static/style.css", "data/books.csv", "library.db"]
print(required_paths())Expected output:
['app.py', 'templates/books.html', 'static/style.css', 'data/books.csv', 'library.db']Mark points:
- includes
app.py; - includes the template path;
- includes the static path;
- includes the CSV data path;
- includes the database file.
Common weak answer:
- listing only folders and not the actual required files.
Answer 2: Smoke Test
Model answer:
def smoke_test():
return "APP STARTED"
print(smoke_test())Expected output:
APP STARTEDMark points:
- defines a small runnable function;
- returns a known message;
- prints the exact smoke-test output.
Common weak answer:
- starting with a large feature before proving the script runs.
Answer 3: Function Test
Model answer:
def valid_category(category):
return category in ("Books", "Stationery")
def run_validation_tests():
assert valid_category("Books") == True
assert valid_category("Stationery") == True
assert valid_category("Food") == False
return "TESTS PASSED"
print(run_validation_tests())Expected output:
TESTS PASSEDMark points:
- implements the validation rule;
- tests
"Books"; - tests
"Stationery"; - tests invalid
"Food"; - returns the pass message only after assertions.
Common weak answer:
- testing only valid categories.
Answer 4: File Inspection
Model answer:
import csv
def first_csv_row(filename):
with open(filename, "r", encoding="utf-8", newline="") as f:
reader = csv.DictReader(f)
return next(reader)
# Test setup: create the supplied CSV file.
with open("products.csv", "w", encoding="utf-8", newline="") as f:
f.write("product_id,name,price,category\n")
f.write("P01,Pen,1.50,Stationery\n")
print(first_csv_row("products.csv"))Expected output:
{'product_id': 'P01', 'name': 'Pen', 'price': '1.50', 'category': 'Stationery'}Mark points:
- opens the CSV file;
- uses the header row;
- reads the first data row;
- returns a dictionary with correct keys;
- returns the exact first record.
Common weak answer:
- hard-coding guessed field names without reading the header.
Answer 5: JSON Inspection
Model answer:
import json
def json_summary(filename):
with open(filename, "r", encoding="utf-8") as f:
data = json.load(f)
return (type(data).__name__, data[0])
# Test setup: create the supplied JSON file.
with open("items.json", "w", encoding="utf-8") as f:
json.dump([{"id": "B01", "title": "Algorithms"}, {"id": "B02", "title": "Networks"}], f)
print(json_summary("items.json"))Expected output:
('list', {'id': 'B01', 'title': 'Algorithms'})Mark points:
- imports/uses
json; - opens the JSON file;
- loads JSON into Python data;
- reports top-level type name;
- returns the first record.
Common weak answer:
- assuming JSON is always a dictionary. The supplied file is a list.
Answer 6: DB Path Check
Model answer:
from pathlib import Path
def db_path(filename):
return str(Path(filename).resolve())
print(db_path("library.db").endswith("library.db"))Expected output:
TrueMark points:
- uses
Path; - resolves the absolute path;
- keeps the filename
library.db; - prints a checkable result.
Common weak answer:
- printing only
"library.db"without proving which directory is being used.
Answer 7: Route Check
This assumes Flask is available in the lab environment.
Model answer:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "OK"
client = app.test_client()
response = client.get("/")
print(response.get_data(as_text=True))Expected output:
OKMark points:
- creates a Flask app;
- defines route
/; - returns
OK; - uses a test client or equivalent local check;
- prints the response text.
Common weak answer:
- defining the route but never testing that it responds.
Answer 8: Submission Script
Model answer:
import tempfile
from pathlib import Path
def missing_files(required):
missing = []
for path in required:
if not Path(path).exists():
missing.append(path)
return missing
with tempfile.TemporaryDirectory() as folder:
task = Path(folder)
# Test setup: create only the files stated in the question.
(task / "templates").mkdir()
(task / "app.py").write_text("")
(task / "templates/books.html").write_text("")
required = ["app.py", "templates/books.html", "static/style.css", "data/books.csv"]
required = [str(task / path) for path in required]
missing = missing_files(required)
print([Path(path).relative_to(task).as_posix() for path in missing])Expected output:
['static/style.css', 'data/books.csv']Mark points:
- accepts a required-path list;
- loops through required paths;
- checks existence;
- appends missing paths;
- returns both missing paths;
- does not falsely report existing files as missing.
Common weak answer:
- checking only
app.py, even though templates and data files are also required.
Answer 9: Debug Print
Model answer:
def debug_value(value):
return repr(value)
print(debug_value(" Books "))Expected output:
' Books 'Mark points:
- uses
repr; - preserves visible quotes/spaces;
- prints the exact debug representation.
Common weak answer:
- using ordinary
print(value), which can hide leading and trailing spaces.
Answer 10: Final Test Plan
Model answer:
def final_dry_run_report(checks):
for name in checks:
if not checks[name]:
return "FIX BEFORE SUBMISSION"
return "READY"
print(final_dry_run_report({"starts": True, "route_ok": True, "db_ok": True}))
print(final_dry_run_report({"starts": True, "route_ok": False, "db_ok": True}))Expected output:
READY
FIX BEFORE SUBMISSIONMark points:
- checks every item in the dry-run dictionary;
- returns
READYonly when all values are true; - detects a failed route check;
- returns the fix-before-submission message;
- produces both expected outputs;
- keeps the final decision clear.
Common weak answer:
- returning
READYif only the app starts, while route or database checks may still fail.