MCS 275 Spring 2024
Emily Dumas
Reminders and announcements:
A few parting words about context managers...
Safest way
#
with CtxMgr() as varname:
thing(varname)
varname.f()
print("Ok.")
#
M = CtxMgr()
with M as varname:
thing(varname)
varname.f()
print("Ok.")
Unsafe analog
#
M = CtxMgr()
varname = M.__enter__()
thing(varname)
varname.f()
M.__exit__(None,None,None)
print("Ok.")
The one on the left still calls __exit__
if there is an exception in the indented block.
Some examples (listed as class - resource)
open
- Open filethreading.Lock
- Thread-exclusive righturllib.request.urlopen
- HTTP connectiontempfile.TemporaryFile
- Temporary file (deleted after use)In computer science, recursion refers to a method of solving a problem that depends on solving a smaller version of the same problem.
Usually, recursion involves a function calling itself.
n
)
to the answer for a slightly smaller input (e.g. n-1
) and a bit of extra work.
Recursive solutions are often contrasted with iterative solutions.
Recursive solutions can always be converted to iterative ones. Often recursive code is shorter.
A function that always calls itself will never finish!
Recursion must include some kind of stop condition—a case in which the function can directly return an answer instead of calling itself.
The classic first example of recursion, computing $$n! = n \times (n-1) \times \cdots \times 2 \times 1.$$
Natural to do recursively because $n! = n \times (n-1)!$ if $n>0$.
The Fibonacci numbers are defined by $$F_0=0,\; F_1=1,\; \text{and }F_n = F_{n-1} + F_{n-2}$$
So the sequence begins $0,1,1,2,3,5,8,13,...$
The definition immediately suggests a recursive implementation.
n
times, always in the same direction0
/1
Let's use $\oplus$ to mean concatenation of binary sequences, so $0110 \oplus 11 = 011011$.
If $A$ is a binary sequence, let $\bar{A}$ denote the sequence with $0$ and $1$ switched, e.g. $\overline{11101} = 00010$
Finally, let $A^r$ denote the sequence in opposite order, e.g. $10010^r = 01001$.
$$PFS(n) = PFS(n-1) \oplus 1 \oplus \overline{PFS(n-1)^r}$$
If you use the infinite paper folding sequence as the binary digits of a real number, you get the paper folding constant.
$$ \begin{split} PFC &= (0.11011001110010011101100\ldots)_2\\ &= 0.85073618820186\ldots \end{split} $$This number is irrational. In 2007 it was shown1 that it is also transcendental, i.e. cannot be expressed in terms of square roots, cube roots, or any solutions of polynomials with rational coefficients.
Active function calls are tracked by the call stack.
Python imposes a limit on the call stack size (hence on recursion depth). Usually max is $\approx$ 1000.
Let's write iterative versions of factorial, Fibonacci, and paper folding. (Or as many as time allows.)