Welcome to Math with Python
Math with Python turns Python into a math notebook: every lesson runs in the browser via Pyodide, so you plot functions, solve systems, differentiate expressions, and fit regressions without installing anything locally. The course builds NumPy and Pandas fluency alongside classic algebra-through-calculus topics, so the code and the math reinforce each other.
Each lesson mixes short explanations with runnable cells: change a coefficient, re-run, and see the plot shift. Follow the numbered lessons in the sidebar at your own pace, take the Practice Exam when you're ready, and use Exam Remediation to focus on what still needs work.
-
1. Solve $2x + 5 = 17$ for $x$.
Subtract 5, then divide by 2 → $x = 6$.
-
2. What is the slope of the line through $(1, 2)$ and $(4, 8)$?
Slope $= \dfrac{8-2}{4-1} = \dfrac{6}{3} = 2$.
-
3. Which point lies on $y = x^2 - 3$?
At $x=2$: $y = 4 - 3 = 1$.
-
4. $\sin(\pi/2) = ?$
Top of the unit circle — $y$-coordinate is 1.
-
5. Solve $x^2 - 5x + 6 = 0$.
$(x-2)(x-3)=0$, so $x = 2$ or $x = 3$.
name = value2. Printing results with
print()3. Arithmetic operators (
+, -, *, /, **)4. Compound interest:
final = principal * (1 + rate) ** years
name = valuestores it; every later line that mentions the name uses the current value- Exponents use
**, not^ - Write the formula once, change one input, re-run — that's the notebook workflow
Python is a calculator that remembers. You assign a value to a name
with =, and every later line that mentions the name gets the
current value. That's what makes it a math notebook instead of a
throwaway calculation.
The Run cell below computes compound interest: an initial deposit of
$1,000 at 5% interest, compounded annually for
10 years. Press Run — this is real code
running in your browser.
principal = 1000
rate = 0.05
years = 10
final = principal * (1 + rate) ** years
print("After", years, "years:", round(final, 2))
print("Interest earned:", round(final - principal, 2))
Order of operations matters: ** (exponent) binds
tighter than *, so principal * (1 + rate) ** years
means $\text{principal} \cdot (1 + \text{rate})^\text{years}$, not
$(\text{principal} \cdot (1 + \text{rate}))^\text{years}$. If you're unsure, add parentheses.
Here's a Tinker cell — a for-loop prints the
balance every year so you can watch the growth curve build
up. Change the interest rate to 0.08, or the number of
years to 30, and rerun to see more rows appear.
principal = 1000
rate = 0.05
years = 10
# Print the year-by-year growth. Try changing rate or years and rerun.
print("year balance")
for t in range(years + 1):
balance = principal * (1 + rate) ** t
print(f"{t:>3} ${balance:>8.2f}")
Floats surprise you sometimes. Python stores decimals
in binary, so 0.1 + 0.2 doesn't come out to exactly
0.3. This isn't a bug — it's the same trade-off every scientific
calculator makes. Try it:
print(0.1 + 0.2) print(0.1 + 0.2 == 0.3) # this is False! print(round(0.1 + 0.2, 10) == 0.3)
Exercise. Use the compound interest formula
$B(t) = \text{principal} \cdot (1 + \text{rate})^t$ to compute the
balance after 20 years of a $2,000 principal at a 6% annual rate.
Assign the result to balance. This is the same
formula the Explore below visualizes — you're computing one
point on that curve.
principal = 2000 rate = 0.06 years = 20 # Apply B(t) = principal * (1 + rate) ** t and assign to `balance`. balance = ...
Bridging Pre-Algebra — fractions and ratios.
Python's built-in fractions.Fraction handles exact
rational arithmetic with no floating-point drift, and percent math
is just multiplication. If you drilled fractions and ratios in
Pre-Algebra, here's what those calculations look like in code.
from fractions import Fraction
# Exact fraction arithmetic — no floating-point drift.
a = Fraction(1, 3)
b = Fraction(2, 5)
print("1/3 + 2/5 =", a + b) # 11/15 exactly
print("1/3 * 2/5 =", a * b) # 2/15 exactly
print("as decimal:", float(a + b)) # 0.7333...
# Percent math — no special library needed, just multiplication.
sticker_price = 199.99
discount = 0.20 # 20% off
tax_rate = 0.0875 # 8.75%
final = sticker_price * (1 - discount) * (1 + tax_rate)
print("final price after 20% off + 8.75% tax:", round(final, 2))
Ratios & proportions. A recipe scales by multiplying every quantity by the same factor. Fractions keep the ratio exact through the scaling.
from fractions import Fraction
# Add 1/10 to itself ten times, then compare to 1 exactly.
# Floats drift; Fractions don't. Try both.
exact = Fraction(0)
approx = 0.0
for _ in range(10):
exact = exact + Fraction(1, 10)
approx = approx + 0.1
print("exact after 10 additions =", exact, "==", exact == 1)
print("approx after 10 additions =", approx, "==", approx == 1)
print("difference:", float(exact) - approx)
Explore. Compound interest is a function of time: $B(t) = \text{principal} \cdot (1 + \text{rate})^t$. Years go in, balance comes out. Slide principal and rate and watch the curve bend.