Module 3 · Foundations

Module 3: construction feedback

Try practice before reading the worked notebook. Download solutions or open notebooks/practice/module03-solutions.ipynb in the complete source tree. If a download link does not open, use the offline access route.

parse_latency

Preserve measured zero and missingness separately. For parse_latency(''), the expected result is None.

def parse_latency(value):
    if value is None or value == "":
        return None
    number = float(value)
    if number < 0:
        raise ValueError("negative latency")
    return number

deduplicate

Deduplicate by identity, not the entire row. For deduplicate([{'event_id': 'a', 'v': 1}, {'event_id': 'a', 'v': 2}, {'event_id': 'b', 'v': 3}]), the expected result is [{'event_id': 'a', 'v': 1}, {'event_id': 'b', 'v': 3}].

def deduplicate(records):
    seen = set()
    kept = []
    for row in records:
        if row["event_id"] not in seen:
            kept.append(row)
            seen.add(row["event_id"])
    return kept

reconcile

Every source row needs one accounted-for outcome. For reconcile(10, 7, 2, 1), the expected result is True.

def reconcile(input_rows, accepted, rejected, duplicates):
    return all(x >= 0 for x in [input_rows,accepted,rejected,duplicates]) and input_rows == accepted+rejected+duplicates

Complete-study results feedback

12 input rows reconcile as 6 accepted plus 6 rejected. The accepted latencies are 12, 18, 25, 45 and 20 ms, plus one missing value, which must be left out rather than counted as 0. The mean of the five observed values is 24 ms and the median is 20 ms, matching the report. These values come from the fixture run during the October 28, 2026 review.

Reasoning task feedback

For example, {'event_id': 'a', 'v': 1} and {'event_id': 'a', 'v': 2}: the rows differ, so whole-row deduplication keeps both, but there is one identity. With one accepted and one duplicate, reconcile(2, 1, 0, 1) is True. The complete script treats this pair as conflicting and rejects both, because it cannot tell which value is correct. State which policy you chose and why.

Applied extension feedback: represent categories

In the recorded run (October 28, 2026), validation balanced accuracy was 0.932 for codes as numbers (30 inputs), 0.949 for one-hot (68 inputs) and 0.949 for one-hot plus the count (69 inputs); false-positive rates were 0.049, 0.037 and 0.037. One-hot creates 68 columns rather than 90 because many attributes use only two of the three codes.

The count adds nothing because its assumption fails: -1 goes with the higher training phishing rate in only 22 of the 30 attributes, so counting -1 codes mixes signals that point in opposite directions. An engineered feature needs a reason that holds in the training data. Carrying one-hot forward is reasonable on this evidence, but the 0.017 gain is on one validation split; confirm it is not split noise (compare the Module 6 stability exercise) before treating it as settled, and keep the final test for the locked choice.

Judge the explanation

Compare your explanation with the criteria in the study workflow: passing the visible checks alone is developing; a changed case that you predict, implement and explain meets the task.

Transfer feedback

Add a repeated event with a changed annotation and a missing latency. Explain the retained record and reconciliation. A defensible response keeps the first record for the repeated event_id under the practice policy, or explains the complete script's conflict rejection. It keeps the missing latency as missing rather than zero, and shows input rows = accepted + rejected + duplicates.