THE GENIUS PROJECT
๐Ÿ Lesson 7 of 9

Python in your browser

๐Ÿ•’ About 45 minutes ๐Ÿงฉ Builds on Lessons 2 and 3 ๐ŸŽฎ Games, charts + animation

Forget the hacker-in-a-hoodie image. Python reads almost like English, and by the end of this lesson you will have built small programs, filled in missing code, drawn a chart, and run a real logistic regression, the same model from Lesson 2, in a few lines. We go slow and use everyday examples, not only football.

๐Ÿงญ How to get through this lesson

Read each short section, then do the little exercise under it before moving on. Do not rush. Every section is one small idea, and they stack. By the last one you are writing machine learning code.

1. A program is a list of steps

A program is like the steps to make a bowl of cereal: get a bowl, pour cereal, add milk, grab a spoon. Order matters. Pour the milk before you get the bowl and you have a mess on the counter. Python runs your steps from the top line to the bottom line, one at a time.

2. Variables: labelled boxes

A variable is a labelled box that holds a value. You put something in with a single =, and use the name later. Imagine you are saving up for new headphones.

๐Ÿ variables
goal = 120          # the headphones cost $120
saved = 45          # you have saved $45 so far
left = goal - saved  # how much more you need

print("You still need $", left)
Output
You still need $ 75

When this runs it prints You still need $ 75. The box called left now holds 75, because the computer worked out 120 - 45 for you.

โœ๏ธ Fill in the blanks

You get 15 dollars allowance a week and want to save for a 90-dollar game. Pick the right words so this prints how many weeks it takes.

price = 90 per_week = 15 weeks = price per_week ("Weeks to save:", weeks)

3. Three kinds of value: text, numbers, true/false

Values come in types. The three you will meet most:

๐Ÿ types
name = "Renee"       # string (text)
age = 15             # number
has_bus_fare = True  # boolean (yes/no)

print(name, "is", age)
Output
Renee is 15
โš ๏ธ Quotes matter

age = 15 is the number fifteen you can do maths with. age = "15" is the text one-five, which you cannot add or subtract. If a value is words, it needs quotes. If it is a number you want to calculate with, no quotes.

4. Lists: many values in one box

A list holds several values in order, inside square brackets. Think of your playlist, or the chores on the fridge.

๐Ÿ lists
playlist = ["Afrobeats", "Dancehall", "Amapiano", "Soca"]

print("First track type:", playlist[0])   # lists start counting at 0
print("How many:", len(playlist))
Output
First track type: Afrobeats
How many: 4

Two things that trip people up at first: lists start counting at 0, so playlist[0] is the first item, not the second. And len(playlist) gives the length, here 4.

5. Loops: do the same thing to each item

A for loop walks through a list and runs the same indented steps for every item. Say you want to count how many days this week you hit your step goal.

๐Ÿ loops
steps = [8200, 10500, 6000, 12000, 9100]
good_days = 0

for day in steps:
    if day >= 10000:
        good_days = good_days + 1

print("Days you hit 10k steps:", good_days)
Output
Days you hit 10k steps: 2

The indentation (the spaces) tells Python which lines are "inside" the loop and the if. This one prints 2.

๐Ÿ’ก One = versus two ==

Single = puts a value in a box: good_days = 0. Double == asks a question: day == 10000 means "is day equal to 10000?" Mixing these up is the number one beginner slip. Keep an eye out in the game below.

โœ๏ธ Fill in the blanks

This should count how many texts in a list were from your best friend "Tanya". Pick the right pieces.

texts = ["Tanya", "Mom", "Tanya", "School", "Tanya"] count = 0 sender in texts: if sender "Tanya": count = count 1 print(count)

6. if / else: making a decision

An if runs code only when something is true. Add else for what happens otherwise. Everyday version: should you carry an umbrella?

๐Ÿ if / else
rain_chance = 70   # percent

if rain_chance >= 50:
    print("Carry the umbrella โ˜”")
else:
    print("You're good ๐Ÿ˜Ž")
Output
Carry the umbrella โ˜”

This is exactly the "decision boundary" idea from Lesson 2: pick a threshold (50%), act one way above it and another way below. Logistic regression makes that same call, it just works out the probability first.

7. Functions: a reusable mini-program

A function is a named recipe you can reuse with different inputs. This tip calculator works for anyone who has ever split a bill.

๐Ÿ functions
def total_with_tip(bill, tip_percent):
    tip = bill * tip_percent / 100
    return bill + tip

print(total_with_tip(2000, 15))   # a $2000 bill + 15% tip = 2300
print(total_with_tip(850, 10))    # reuse it with new numbers = 935
Output
2300.0
935.0

def starts the recipe, the words in brackets are its inputs (parameters), and return hands back the answer. Write it once, use it forever with different numbers.

โœ‹ Quick check
In Python, what does sender == "Tanya" mean?

8. ๐ŸŽฎ Build a program: drag the lines in order

Time to put steps in order yourself. The lines below are shuffled. Drag each into the numbered slots so the program runs top to bottom correctly, then press Run. Indented lines go inside the loop or if above them.

๐Ÿ–ฑ๏ธ How to play

Press and hold a code line, drag it into a slot on the right, and let go. On a phone, drag with your finger. Drop a line on a full slot to swap it back out. When every slot is filled, press Run. Coral lines are out of place, fix them and run again.

Round 1: count the wins

Goal: count how many wins are in a list of last-five results, and print the total (the answer is 3).

Code lines (drag from here)
Your program (drop in order)

9. The logistic regression formula, as code

Remember the Lesson 2 formula? Here it is as a Python function. The maths and the code are literally the same thing.

$$P(\text{win}) = \dfrac{1}{1 + e^{-z}} \quad\text{where}\quad z = -0.4 + 0.05\,x_1 + 0.3\,x_2 + 1.1\,x_3$$
๐Ÿ the sigmoid, by hand
import math

def win_probability(ranking_gap, recent_form, is_home):
    home = 1 if is_home else 0
    z = -0.4 + 0.05 * ranking_gap + 0.3 * recent_form + 1.1 * home
    return 1 / (1 + math.exp(-z))

print(win_probability(26, 3, True))   # 0.9478..., the same 95% from Lesson 2
Output
0.9478706836215559

Round 2: rebuild that function

Drag these into order so the program prints the win probability for the Team Gold match (ranking gap 26, form 3, at home). Correct order prints 0.95.

Code lines (drag from here)
Your program (drop in order)

10. The full logistic regression solution

You will almost never write the training loop by hand. A free library called scikit-learn already has both models built in. This is a complete logistic regression program, from data to a prediction, the kind you would actually run in Colab. The comments walk through every line.

๐Ÿ full solution: train and predict with logistic regression
# Step 1: bring in the tool
from sklearn.linear_model import LogisticRegression

# Step 2: the training data.
# each row is one past match: [ranking_gap, recent_form, is_home]
X = [[26, 4, 1], [5, -1, 0], [-10, 2, 1], [30, 5, 1],
     [-20, -3, 0], [8, 0, 1], [-5, 1, 0], [15, 3, 0]]
y = [1, 0, 1, 1, 0, 1, 0, 1]   # 1 = they won, 0 = they did not

# Step 3: train the model. .fit() runs the guess-check-adjust loop for you.
model = LogisticRegression().fit(X, y)

# Step 4: predict a brand new match: gap 22, form 2, at home
todays_match = [[22, 2, 1]]
prob = model.predict_proba(todays_match)[0][1]

print("Win probability:", round(prob, 2))
print("Prediction:", "WIN" if prob >= 0.5 else "NOT A WIN")
Output
Win probability: 0.74
Prediction: WIN

That is a complete machine learning program. X is your features table, y is the labels, .fit(X, y) is the training, and predict_proba hands back the probability, exactly like the sigmoid you calculated by hand. Swap logistic regression for a decision tree and only one line changes.

โœ๏ธ Fill in the key lines

This trains a decision tree instead and makes a prediction. Choose the right pieces.

from sklearn.tree import model = DecisionTreeClassifier(max_depth=3).(X, y) answer = model.([[22, 2, 1]]) print(answer)
๐Ÿ” How little actually changed

Going from logistic regression to a decision tree, only the import and the model name changed. The data (X, y), the .fit(), and the predict step stay the same. That is what makes scikit-learn so handy: once you know the pattern, you can try any model with a one-line swap.

11. Draw a chart of the World Cup

Numbers in a list are hard to feel. A chart makes a story jump out. Python's matplotlib is the go-to tool, and it is already installed in Colab. Start with a bar chart of goals scored by six of the teams left in the tournament.

๐Ÿ bar chart: goals scored
import matplotlib.pyplot as plt

teams = ["Argentina", "Spain", "France", "England", "Morocco", "Norway"]
goals = [12, 11, 10, 9, 7, 8]

plt.figure(figsize=(8, 4))
plt.bar(teams, goals, color="#2bf0c8")
plt.title("Goals scored so far, World Cup 2026")
plt.ylabel("Goals")
plt.show()
Output
04812121110978ArgentinaSpainFranceEnglandMoroccoNorwayGoals scored so far, World Cup 2026
A window pops up with this chart.

Three lines do the real work: plt.bar draws the bars, plt.title and plt.ylabel label it, and plt.show() paints it on screen. Swap in your own teams and numbers and run it again.

Now a scatter plot, which is how analysts compare expected goals (xG) against goals a team actually scored. Points above the dashed line finished better than expected (clinical), points below wasted their chances.

๐Ÿ scatter: expected vs actual goals
import matplotlib.pyplot as plt

teams = ["ARG", "ESP", "FRA", "ENG", "MAR"]
xg     = [10.5, 9.2, 11.0, 6.8, 7.5]   # expected goals
actual = [12, 11, 10, 9, 7]         # goals they really scored

plt.scatter(xg, actual, s=120, color="#ffc800")
for i in range(len(teams)):
    plt.annotate(teams[i], (xg[i], actual[i]))
plt.plot([5, 12], [5, 12], "--", color="gray")  # "scored exactly as expected" line
plt.xlabel("Expected goals (xG)")
plt.ylabel("Actual goals")
plt.title("Better or worse than expected?")
plt.show()
Output
681012681012ARGESPFRAENGMARBetter or worse than expected?Expected goals (xG) → ยท dashed line = scored exactly as expected
Points above the dashed line overperformed their xG.
โœ๏ธ Fill in the chart code

This should draw a bar chart of how many matches each team has won. Choose the right pieces.

import matplotlib.pyplot as plt teams = ["Curaรงao", "Haiti", "Morocco"] wins = [1, 1, 4] plt.(teams, wins, color="#2bf0c8") plt.("Wins so far") plt.()

12. Make the chart move

A still chart shows the final numbers. An animation shows how they got there, match by match. matplotlib can do this with FuncAnimation, which calls a small update function once per frame. This one grows Argentina's running goal total across the tournament.

๐Ÿ animation: goals piling up match by match
import matplotlib.pyplot as plt
from matplotlib import animation
from IPython.display import HTML

# Argentina's total goals after each match
running_total = [0, 1, 1, 3, 4, 6, 7]

fig, ax = plt.subplots()
ax.set_xlim(0, len(running_total) - 1)
ax.set_ylim(0, max(running_total) + 1)
ax.set_title("Argentina: goals piling up match by match")
line, = ax.plot([], [], color="#00cfe8", linewidth=3, marker="o")

def update(frame):
    line.set_data(range(frame + 1), running_total[:frame + 1])
    return (line,)

anim = animation.FuncAnimation(fig, update, frames=len(running_total), interval=500)
HTML(anim.to_jshtml())   # gives you a play button right inside Colab
Output (press Run again to replay)
02468M1M2M3M4M5M6M7Argentina: goals piling up match by match
A play button appears in Colab; here it just animates.

Read it as a loop: update(0) draws the first match, update(1) adds the second, and so on. interval=500 waits half a second between frames, and to_jshtml() turns the whole thing into a little video player with a play button in your notebook.

โ–ถ๏ธ Run these in Colab

Charts and animations show up best in Google Colab (next lesson). Paste any of these cells in, press Shift + Enter, and the chart appears right under the code. Change the teams or numbers to whatever match you are watching tonight.

๐Ÿง  Recap
  • A program runs top to bottom; indentation shows what is inside a loop or if.
  • Variables hold values, lists hold many, loops repeat, if/else decides, functions are reusable recipes.
  • Single = assigns; double == compares.
  • scikit-learn trains a model with .fit(X, y), and you predict with predict or predict_proba.
  • Swapping models is often a one-line change.
  • matplotlib draws charts (plt.bar, plt.scatter) and even animations (FuncAnimation).

Next: where to actually run all this, for free, in your browser.