lru_cache: the decorator you already understand
In lesson 5-2 you sketched a caching decorator. The standard library ships a production-grade one, functools.lru_cache. Stick it on any pure function (same inputs, same output, no side effects) and repeat calls become dictionary lookups:
from functools import lru_cache @lru_cache(maxsize=None) def fib(n): if n < 2: return n return fib(n - 1) + fib(n - 2)
Without the cache, fib(35) recomputes the same subproblems millions of times. With it, each fib(k) is computed once. This technique, memoization, reappears as dynamic programming in the Algorithms course.
Caching is the rare optimization that is both free to add and safe, provided the function really is pure, which is why lru_cache shows up in virtually every serious Python codebase.
Code exercise · python
Run this program. fib(80) finishes instantly because every subresult is cached. cache_info shows the hits.
The math module in sixty seconds
You used + - * / // % ** in Python for Beginners. math adds the rest:
import math math.sqrt(2) # 1.4142135623730951 math.floor(3.7) # 3, round down math.ceil(3.2) # 4, round up math.gcd(12, 18) # 6, greatest common divisor math.pi # 3.141592653589793 math.inf # infinity, a useful "worse than anything" start value
math.inf deserves a note: when hunting for a minimum, initialize best = math.inf and any real value will beat it. You will use exactly that trick in the unit 10 capstone.
Code exercise · python
Your turn. Find the cheapest price using the math.inf pattern: start best at infinity, loop, and keep the smaller of best and each price (min works). Print best at the end.
Quiz
lru_cache is safe to add to which kind of function?
Quiz
When hunting for a MINIMUM, why start best = math.inf rather than best = 0?