Skip to lesson content

PYTHON / LESSON 18 OF 18

Revision and interview practice

Read the explanations, work through the examples, and complete the student tasks.

Learning goals

Connect the course topics, explain key language behavior, and build a complete small program.

Worked example A student results summary

This program combines functions, iteration, conversion, validation, exceptions, dictionaries, sorting, formatted output, and JSON file handling. It creates or replaces summary.json in the current folder.

import json
from pathlib import Path
def summarize(records):
    accepted = []
    rejected = []
    for row_number, record in enumerate(records, start=1):
        try:
            name = record["name"].strip()
            score = int(record["score"])
            if not name or not 0 <= score <= 100:
                raise ValueError("Invalid name or score")
        except (KeyError, ValueError, TypeError, AttributeError):
            rejected.append(row_number)
            continue
        accepted.append({"name": name, "score": score})
    average = None
    if accepted:
        average = sum(row["score"] for row in accepted) / len(accepted)
    return {"students": sorted(accepted,
                               key=lambda row: row["score"],
                               reverse=True),
            "average": average, "rejected_rows": rejected}
records = [{"name": " Ali ", "score": "75"},
           {"name": "Sara", "score": "95"},
           {"name": "Bilal", "score": "wrong"}]
summary = summarize(records)
Path("summary.json").write_text(json.dumps(summary, indent=2),
                                encoding="utf-8")
for student in summary["students"]:
    print(f"{student['name']}: {student['score']}")
print("Average:", summary["average"])
print("Rejected rows:", summary["rejected_rows"])

Expected output:

Sara: 95
Ali: 75
Average: 85.0
Rejected rows: [3]

The input contract is a list of dictionaries whose fields contain text, as CSV records do. strip normalizes names. The try block isolates record validation so one bad row does not end the batch. An all-invalid input produces average None rather than dividing by zero. JSON represents None as null. Sorting produces a new list instead of changing the input.

Additional revision tools

math supplies numeric functions, re handles regular expressions, and collections includes specialized containers such as Counter. This example counts simple words and extracts digit sequences:

import re
from collections import Counter

print(re.findall(r"\d+", "Order 12 has 3 items"))
counts = Counter("python sql python".split())
print(counts.most_common(1))
print(min([3, 1, 2]), max([3, 1, 2]), sum([3, 1, 2]))
print(round(12.345, 2))

Expected output: ['12', '3'], then [('python', 2)], then 1 3 6, then 12.35. round uses Python's rounding rules and binary floating point; it is not a substitute for choosing an appropriate money representation.

Interview questions and model answers

1. What is dynamic typing? Names can be rebound to objects of different types; each object still has a type.

2. How do == and is differ? The first compares equality; the second checks whether two references identify the same object.

3. How do a list and tuple differ? Both are ordered sequences; a list is mutable and a tuple's item references cannot be reassigned.

4. Why use a set? For unique hashable items and efficient membership checks, without positional indexing.

5. Does a dictionary preserve order? It preserves insertion order. It does not automatically sort keys.

6. What does a function return without an explicit value? None.

7. How do break, continue, and pass differ? Exit the nearest loop, skip to its next iteration, and perform no action, respectively.

8. Why use with for files? It closes the file when the block exits, including through an exception.

9. Why can a generator use less memory? It yields values as requested instead of retaining an entire produced list.

10. What is polymorphism? Different objects provide the same operation through a shared calling interface.

11. Why use a virtual environment? It isolates project dependencies from other environments.

12. Is Python purely interpreted with no compilation? That description is incomplete: CPython normally compiles source to bytecode before executing it.

Student tasks and final project

1. Extend summarize to include pass_count and fail_count with a pass threshold of 50. Test scores 49 and 50.

2. Read records from a CSV file instead of the embedded list. Preserve row numbers and report a reason for each rejected record.

3. Add a JSON output path argument and move execution into main with an __name__ guard. Keep summarize free of file-writing side effects.

4. Test mixed valid and invalid input, empty input, all-invalid input, duplicate names, and scores outside 0 to 100. Decide and document whether duplicate names represent separate records.

5. Build a final results tool that produces a sorted report and JSON summary. Optional extension: generate a bar chart or implement a Student class with validation.

Completion check: valid records are retained, invalid rows are reported, empty input does not crash, and the average uses only accepted scores. Submit source code, sample input, generated output, tests, and a README. Be prepared to explain each line of your validation and aggregation code.