Summarizing Your Data

Recap and Feedback


The promise at the start of this part was simple: by the end, your study log would say something useful about the data it has been collecting. It now does. If you open the program tomorrow, the opening dashboard will tell you what you have spent time on, how much you have done in the last week, which days were heaviest, and whether you are on a streak.

The part focused on summaries — small facts about data. Creating them involves counting matching items, totalling them, averaging them, grouping by a category, selecting a window of time, ranking them, picking the best, walking a series for streaks. Each pattern is a loop — often a single-pass loop — that walks the data and updates a running result.

The patterns are not all the same; the variety is what makes the part interesting. The recap is easier to hold in mind if it is organised by family.

The Families of Summaries

Filtered scalar summaries. How many matching sessions? How many matching minutes? What is the average? These come straight out of Part 2’s counting and accumulator loops, applied to rows. The new fluency move is unpacking the row in the loop header, and the new design habit is the empty-case answer from the summary contract — counts and totals return zero, averages return None.

Grouped summaries. How many sessions per subject? Total minutes per subject? Average minutes per subject? These are the per-category questions, written with lists alone in a two-pass shape that walks the data once per category. The next part replaces the inner loop with a single dictionary update and shrinks the function considerably.

Time-window summaries. How many minutes in the last seven days? Which sessions happened between X and Y? These need dates as real values — parsed with date.fromisoformat, compared with < and ==, subtracted to get gaps, added to with timedelta. The inclusive-window rule (start <= day <= end) appears throughout the rest of the part.

Ranking and best-of summaries. What were the three longest sessions? Which day was heaviest? The two questions need different tools. sorted(rows, key=by_field)[:n] produces ranked answers; a “best so far” loop with > (not >=) picks the single best row and gives a free tie policy of “earliest wins.” Both depend on small named key functions.

Daily summaries. How many minutes per day? Which day was heaviest? These reuse the grouped-summary pattern with the date as the category, and compose cleanly with date windows to produce “the last seven days, by day.”

Streak summaries. Current streak? Longest streak? The capstone — a single-pass loop over the sorted list of distinct days, with the consecutive-day test from date subtraction, and an explicit rule for what “alive” means. Streaks are also the chapter where the Part 4 plausible-but-wrong instinct gets the most exercise, because the happy path hides the cases where the function is actually wrong.

Recap Quiz

The recap quiz below is a short sequence of questions drawn from the main ideas of this part. Complete it before the feedback form.

Feedback

Next, please take a moment to reflect on your work in this part and provide feedback. Your input helps us improve the course materials.

Reflection and feedback

0 / 5 points

Consider the following statements and answer them based on your experiences from studying the materials and working on the assignments in this part. When answering the numeric statements, answer them so that value 1 means that you strongly disagree with the statement, and value 7 means that you strongly agree with the statement. Please be as honest as possible when answering. The feedback will be used to improve the course.

Looking Ahead

At this point, the per-subject summary functions — the ones with the two-pass nested-loop structure — are doing what they are doing because lists do not offer a way to map a category directly to a running summary.

In the next part, we will learn about dictionaries, which are a tool that does provide a mapping from each category to a running summary, so the code can update the summary for each session in a single pass. The version of summaries_by_subject shrinks to a handful of lines, one pass through the data, and is clearer to read than this part’s version. The repeated “find the unique values of a column, then loop again to summarise each one” shape gets replaced by a single totals[subject] += minutes-style update.

We will also learn how to store data in JSON format, which is more natural for nested and named data than CSV, and will take a look at classes that are a way to give names to the fields in a row, so you can write session.minutes instead of session[1].

The AI thread will continue as well. The focus will be on critiquing data designs. When the data shape is “list of fields,” there is not much to discuss. When it can be a list, a dictionary, a nested structure, or a different shape entirely, design decisions appear — and design decisions are exactly the place AI assistants are most likely to produce a plausible-looking answer that the next maintainer will quietly regret.