Welcome. This is step 1 of the Guided Foundations Path, and it assumes no programming and no calculus. By the end you can run every later lab, and read a sum, an average, an area under a curve, and a slope.
The readings 2, 4, 6, and 8 sum to 20 and average 5, and a curve is read as thin rectangles for area and as a rise over a run.
Nothing to install. Each shaded block on this page runs in your browser.
What the Run cell does#
A block like the one below is a live Python cell:
readings = [2.0, 4.0, 6.0, 8.0]
total = sum(readings)
print("total:", total)
- Run sends the code to a Python interpreter downloaded into your browser. The output appears underneath. Nothing is installed on your computer.
- Edit lets you change the code and run it again.
print(...) is how the cell speaks. Unprinted work stays invisible. Cells do not share memory, so each lab below re-imports numpy.
Press Run on the cell above. You should see:
total: 20.0
How to read an error message#
A failure names the spot where Python stopped. Mistype readings as readigs:
Traceback (most recent call last):
File "<exec>", line 2, in <module>
NameError: name 'readigs' is not defined. Did you mean: 'readings'?
Read a traceback from the bottom up. The last line names the problem. NameError means the name was never defined, and Python often guesses the typo. The lines above point at line 2. A typo, a missing import, or bad indentation covers most first errors. Fix the line and run again.
Variables: giving a value a name#
A variable is a name attached to a value. You create one with =.
celsius = 20.0
fahrenheit = celsius * 9 / 5 + 32
print("celsius:", celsius)
print("fahrenheit:", fahrenheit)
Python evaluates the right-hand side, then attaches the name on the left. Multiplication and division happen before addition.
An integer is a whole number, such as 3 or -7. A float has a decimal point, such as 3.0 or 20.5. Reassigning a name points it at the new value:
steps = 10
steps = steps + 5
print(steps)
Lists: many values under one name#
A list holds several values in order, written with square brackets and commas.
sensor_readings = [12.5, 12.1, 12.9, 12.3]
print("all readings:", sensor_readings)
print("how many:", len(sensor_readings))
print("first:", sensor_readings[0])
print("last:", sensor_readings[-1])
Positions start at 0, so [0] is the first value and [1] is the second. [-1] counts from the end. len(...) is the length.
Making decisions: if and else#
An if runs its block only when the condition is true. The indentation marks the block. Python uses it instead of brackets.
battery_percent = 18
if battery_percent < 20:
print("Low battery: returning to the charging station.")
else:
print("Battery fine: continuing the task.")
Change 18 to 85 and the else branch runs. Comparisons are ==, !=, <, <=, >, and >=. A single = assigns a name. A double == asks whether two values are equal.
Repeating work: for loops#
A for loop runs the same block once for every value in a list.
readings = [2.0, 4.0, 6.0, 8.0]
total = 0.0
for r in readings:
total = total + r
print("sum found by the loop:", total)
For each value r in readings, add r to total. The name r is arbitrary. This loop is what sum(...) does.
Functions: naming a block of work#
A function is a named block you can run again. Define it with def, then call it by name.
def average(values):
return sum(values) / len(values)
print("average of four readings:", average([2.0, 4.0, 6.0, 8.0]))
print("average of two readings:", average([10.0, 20.0]))
def names the function and its inputs. return hands the result back to the caller. The body is indented, and the blank line after it ends the function. The same average works on any list of numbers.
numpy arrays: math on the whole list at once#
Labs use numpy arrays. They look like lists, and arithmetic hits every element at once. numpy is already loaded. Import it.
import numpy as np
readings = np.array([2.0, 4.0, 6.0, 8.0])
print("the array:", readings)
print("add 10 to every element:", readings + 10)
print("multiply every element by 2:", readings * 2)
print("element-by-element square:", readings ** 2)
print("mean (average):", readings.mean())
print("sum:", readings.sum())
print("first element:", readings[0], "last element:", readings[-1])
readings * 2 doubles every value. On a plain list, * 2 repeats the list. That step is elementwise: one line updates a whole batch of readings.
readings[0] is the first element and readings[-1] the last. readings[1:3] keeps positions 1 and 2, stopping before the second index.
The math the labs use#
Four ideas return in nearly every later lab. The symbols below are the code above, written short.
Sums#
A sum adds every value. Sigma is the loop from to .
Python writes sum(values) or arr.sum(). These readings add to .
Averages#
An average (the mean) divides the sum by the count. It is the one value that would match the total if every reading were equal.
sums to over values, so the average is . That one number hides the spread, which the probability lessons on this path take up.
Area under a curve#
Distance at a changing speed is the area under the speed curve. Split the trip into short slices. Inside one slice the speed is nearly constant, so the distance there is about speed times slice width. Adding the rectangles gives the area.
Thinner slices sit closer to the curve. In the lab, np.sum(y[:-1]) * width adds the left-edge rectangles. The limit is a definite integral. A probability density is an area in the same sense.
Slope as a rate#
A slope is rise over run.
A slope of adds to for each extra unit of . On a line it is constant. On a curve, measure it between two nearby points. The limit is the derivative, or a partial derivative when there is more than one input. Later labs still mean a slope.
Browser lab: sums, averages, area, and slope#
This lab runs all four ideas on one small dataset. Press Run, then read the output line by line.
import numpy as np
import matplotlib.pyplot as plt
# --- Part 1: sum and average of a list of readings ---
readings = np.array([2.0, 4.0, 6.0, 8.0])
print("readings:", readings)
print("sum:", readings.sum())
print("average:", readings.mean())
# --- Part 2: area under the curve y = x^2 between x = 0 and x = 2 ---
# We tile the area with n thin rectangles and add their areas.
n = 100
x = np.linspace(0.0, 2.0, n + 1) # n + 1 edges, from 0.0 to 2.0
y = x ** 2 # height of the curve at each edge
width = x[1] - x[0] # every slice has the same width
height = y[:-1] # left edge of each rectangle
area = np.sum(height) * width
print("rectangles:", n)
print("estimated area under x^2 on [0, 2]:", round(float(area), 4))
print("exact area (x^3 / 3 from 0 to 2):", round(8 / 3, 4))
# --- Part 3: slope of y = x^2 near x = 1 ---
x1, x2 = 1.0, 1.1 # two nearby points
rise = x2 ** 2 - x1 ** 2
run = x2 - x1
print("slope of x^2 near x = 1:", round(rise / run, 4))
# --- Picture: the rectangles tile the area under the curve ---
fig, ax = plt.subplots(figsize=(6, 4))
ax.bar(x[:-1], height, width=width, align="edge",
color="tab:blue", alpha=0.3, label="rectangles")
ax.plot(x, y, color="tab:red", linewidth=2, label="y = x^2")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_title("Area under y = x^2 on [0, 2]")
ax.legend()
plt.show()
print("Notice: the four readings sum to 20 with average 5; 100 rectangles give area 2.6268 against the exact 8/3 = 2.6667 (more slices would close the gap); and the slope of x^2 near x = 1 is about 2.1.")
What to look for:
- Sum and average match the hand calculation: and .
- Area sits a little under the exact . Left-edge rectangles fall under a rising curve. Set
nto1000and the estimate moves closer. - Slope is about
2.1betweenx = 1andx = 1.1. Setx2 = 1.01and it moves toward2.
Knowledge Check#
Test the loop and array behaviour and the slope and area ideas from above.
The slope of a line is its rise divided by its ______.
What does `np.array([1, 2, 3]) * 2` produce?
A lab estimates the area under a curve by adding up thin rectangles. If you use more, thinner rectangles, the estimate usually ______.
How many times does the body of `for r in [4, 8, 15, 16]: print(r)` run?
Your turn: predict, then check#
The cell below has two blanks. Read it and write down the output you expect before you run it.
import numpy as np
# 1. Change these four readings to any numbers you like.
readings = np.array([12.0, 15.0, 9.0, 14.0])
# 2. Fill in the average. Hint: numpy has a mean function.
average = None
# 3. Fill in the slope between the points
# (x = 1, y = readings[0]) and (x = 3, y = readings[2]).
# slope = rise / run = (y2 - y1) / (x2 - x1)
slope = None
print("average:", average)
print("slope:", slope)
Replace the first None with the average and the second with the slope from readings[0] to readings[2]. The run is 3 - 1 = 2. Predict both numbers, then run the cell.
For the readings already in the cell: the average is 12.5 (they sum to 50 over 4 values) and the slope is −1.5 (the reading falls 3 over a run of 2).
Key takeaways#
- Run executes the cell in the browser.
print(...)shows the work. Read a traceback from the last line up. - Variables name values, lists count from
0,ifchooses,forrepeats, anddefnames a function. readings * 2doubles a numpy array. On a plain list,* 2repeats the list.- A sum adds, an average divides by the count, an area adds thin rectangles, and a slope is rise over run.
- Predict, then change the cell and explain the output. Later labs assume that.
Next lesson#
Next: Probability Spaces and Events is step 2 of the Guided Foundations Path. Every lab from here on is a Python cell like the ones above, using the same four ideas.
Reading is free. PDF and ePub unlock with the newsletter. Join once and every lesson opens in this browser.