Lesson 2: Loops and remainders
Build the times table on a circle in Python, and learn on the way:
- a for loop over pairs with zip
- the remainder % and angles that wrap around
- a line from two points with plt.plot
- exploring by changing one parameter
Watch it first
Plays from YouTube after a click.
The script
Open in Colab: this lesson as a notebook"""Times table on a circle: N dots, each dot n joined to dot (k * n) mod N.
Run: python times-table.py (needs: pip install numpy matplotlib)
"""
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("dark_background")
N, k = 200, 2 # the number of dots and the multiplier
start = 2 * np.pi * np.arange(N) / N # dot n at the angle 2*pi*n/N
end = start * k # dot k*n: angles wrap around the circle by themselves (that is the "mod N")
plt.figure(figsize=(6, 6))
for a, b in zip(start, end):
plt.plot([np.cos(a), np.cos(b)], [np.sin(a), np.sin(b)], color="#f5c76b", linewidth=0.6)
plt.axis("equal")
plt.axis("off")
plt.show()
# Try: k = 3 for the nephroid, k = 101 to see it collapse into diameters
No Python on this computer? The notebook runs the same script, the exercises and the answers in your browser, on Google Colab.
Line by line
N, k = 200, 2Two names at once: 200 dots and the multiplier 2. These are the two numbers to change.
start = 2 * np.pi * np.arange(N) / NThe angle of each dot: dot n sits at 2π·n / N, so the 200 dots share the circle evenly.
end = start * kThe angle of dot k·n. An angle past 2π simply goes round again, and that does the wrapping (k·n mod N) for us.
for a, b in zip(start, end):zip pairs the two arrays: each time round, the loop gets one start angle with its end angle.
plt.plot([np.cos(a), np.cos(b)], [np.sin(a), np.sin(b)], color="#f5c76b", linewidth=0.6)plt.plot takes the x values, then the y values, of the line’s two ends: one chord of the circle each time round.
Try it yourself
Draw times 3 and times 4. How many cusps (sharp points) does each curve have?
Hint
Change k.
Answer
Times 3 gives the nephroid with 2 cusps, times 4 a curve with 3: always k − 1.
With 200 dots, which dot does 150 × 2 land on? Work it out with the remainder operator.
Hint
In Python, % gives the remainder after dividing.
Answer
(150 * 2) % 200 is 100.
Use 20 dots instead of 200. Why is the heart harder to see?
Hint
Change N.
Answer
With 20 dots there are only 20 lines, too few for the curve they all touch to show.
Quiz
Flashcards
Read the front, say the back to yourself, then open the card.
zip(a, b)
Pairs two sequences item by item: (a[0], b[0]), (a[1], b[1]), …
x % n
The remainder of x divided by n: 300 % 200 is 100.
plt.plot([x1, x2], [y1, y2])
A line from (x1, y1) to (x2, y2).
Envelope
The curve that every line of a family just touches: here, the cardioid.
Times k on a circle
A whole multiplier k draws a curve with k − 1 cusps.