← Data detective

Totals and the biggest

Add up a column, divide for the average, and keep the biggest so far, one row at a time.

Average speed, top scorer, longest song: most questions about data are a total, an average or a biggest.

Last lesson you picked rows out of the table. Now you will work out things about the rows: a total, an average, and the longest song. Each one is a variable that changes as the loop goes through the rows.

PredictRead the code and say what it will do before you run anything. A wrong guess is fine: it shows you what to look for.

Predict

totals.py
total = 0
for n in [3, 4, 5]:
    total = total + n
print(total / 3)

Follow total through the loop: what is it after each number? Then what does / 3 give?

What does it print?

RunRun it and compare the result with your prediction.

Run

Run it. total adds up every song's minutes; longest keeps the longest song found so far. round(x, 1) rounds to one decimal place.

totals.py
import csv

with open("music.csv") as f:
    songs = list(csv.DictReader(f))

total = 0
longest = songs[0]
for song in songs:
    minutes = float(song["minutes"])
    total = total + minutes
    if minutes > float(longest["minutes"]):
        longest = song

print("Average length: " + str(round(total / len(songs), 1)) + " minutes")
print("Longest: " + longest["title"] + " (" + longest["minutes"] + " minutes)")
Try it yourselfYour edits are saved in this browser.

InvestigateTrace how each line of code connects to what you see.

Investigate

totals.py
import csv

with open("music.csv") as f:
    songs = list(csv.DictReader(f))

total = 0
longest = songs[0]
for song in songs:
    minutes = float(song["minutes"])
    total = total + minutes
    if minutes > float(longest["minutes"]):
        longest = song

print("Average length: " + str(round(total / len(songs), 1)) + " minutes")
print("Longest: " + longest["title"] + " (" + longest["minutes"] + " minutes)")

The total and the longest, row by row.

Why the first song.

A total that only keeps the last song.

The first three songs are Jolene (2.7), Bohemian Rhapsody (5.9) and Billie Jean (4.9). Fill in total and the longest minutes after each one.

songminutestotallongest minutes
Jolene2.72.72.7
Bohemian Rhapsody5.9
Billie Jean4.9

Why does longest start as songs[0], not 0?

This should add up the minutes of every song, but it prints only 3.3, the length of the last song. Click the line that is wrong.

ModifyChange the code on purpose and check the result.

Modify

Print the average length of the rock songs only. len(songs) counts every song, so you need a count of your own.

Need a hint?

Start count = 0 beside total = 0.

Another hint

Put the adding inside if song["genre"] == "rock": and add 1 to count there too. Then divide by count.

Also print the oldest song and its year, in the same loop.

Need a hint?

Copy the idea of longest: oldest = songs[0], then replace it when int(song["year"]) is smaller than int(oldest["year"]).

Try it yourselfYour edits are saved in this browser.

Print the average length of the rock songs only.

    Run your program. This ticks when your code does all of the above.

    Also find and print the oldest song.

      Run your program. This ticks when your code does all of the above.

      MakeBuild something new using what you have learned. Expect a few tries; that is normal.

      Genre stats

      Ask for a genre, then print how many songs it has, their average length and its shortest song. If nobody types a genre that is there, say so instead of crashing (dividing by a count of 0 is an error).

      Try it yourselfYour edits are saved in this browser.

      Ask for a genre, then print its number of songs, their average length and its shortest song.

        Run your program. This ticks when your code does all of the above.

        Info

        Where this leads

        Next: count every genre at once, and draw the counts as a bar chart.

        A spreadsheet's AVERAGE() and MAX() give the same answers. Why learn the loop?

        For teachers

        Students total a column, divide for an average and track the longest song with a biggest-so-far variable, then restrict the average to one genre, find the oldest song and write genre stats that cope with no matches. About 50 minutes.

        Open the teacher guide: answers, solutions, slides and a worksheet.

        Students will be able to

        Before class

        Read the unit primer first. Two patterns carry the lesson. The accumulator: total = 0 before the loop, total = total + x inside it (the bug task replaces instead of adding). The biggest so far: start with the first row, and replace it only when a row beats it. float() turns "3.9" into a number (minutes have decimals; years use int()). An average of some rows needs its own count, since len(songs) counts every song; with no matching rows the count is 0 and dividing by it is an error, which the Make asks students to handle. round(x, 1) is used once for tidy output.

        Running the lesson

        1. Predict: write total on the board and update it aloud for each number.
        2. Investigate: do the trace together, then ask why Billie Jean does not replace Bohemian Rhapsody.
        3. Modify: ask where the count must go up: inside the if, beside the adding.
        4. Make: ask students for a genre that is not in the data, and what their program does with it.

        The hard part (on purpose)

        The biggest-so-far pattern. Ask students to fill in the trace by hand before running anything; resist writing the comparison for them.

        When students get stuck

        Stretch and support

        Stretch: Find the longest song of each decade (the 1980s, the 1990s...), using year // 10 * 10 for the decade.

        Support: Give students the rock average with the count already added, and ask them to do the oldest song by copying the longest pattern.

        Where it leads

        Next lesson counts every genre at once with a dictionary and draws a bar chart. In pandas (Lesson 5) these become one-word methods such as .mean() and .max().

        What each step is for

        Now you can
        Next lesson3. A bar chart in textCount every genre at once with a dictionary, then draw each count as a bar of