Sage Shaw - Oct 26th, 2023
Graduate Student Seminar
Would you rather...
spend 50% less time waiting for code to finish?
spend 50% less time writing code?
Do you use Python? v3.11
Do you work with sequences? (yes you do)
Are your codes proceedural?
Functional?
Object oriented?
Have you written a class?
An __iter__
method?
A generator comprehension?
How many keywords do you recognize (use)?
False await else import pass None break except in raise True class finally is return and continue for lambda try as def from nonlocal while assert del global not with async elif if or yield match case
Types of loops
Loops are a kind of control flow.
Often defined as a primitive recursive function.
What kind of loops are these?
n = 0
while not done(n):
print(n)
n += 1
from itertools import count as nonnegative_integers
for n in nonnegative_integers():
if done(n): break
print(n)
Python "for loops"
# What you write
for n in range(3):
# loop body
print(n)
# What happens behind the scenes
generator_object = range(3).__iter__()
while True:
try:
n = generator_object.__next__()
except StopIteration:
break
# loop body
print(n)
Why does Python work this way?
Python loops are flexible
for x, y in zip(x_values, y_values):
for alpha, beta in product(alphas, betas):
for time, u, v, w in solver.solution_generator():
for index, state in enumerate(markov_chain):
Look like functions.
def example():
yield 1
yield 2
yield 3
But returns generator objects.
def example():
yield 1
yield 2
yield 3
gen = example()
type(gen) # class 'generator'
next(gen) # 1
next(gen) # 2
next(gen) # 3
next(gen) # StopIteration exception
A unit of code should be responsible for one thing.
(First in the SOLID principles.)
How many things is this function doing?
def newton_old(x0, f, df):
seq = [x0]
x = x0
for _ in range(10):
x = x - f(x) / df(x)
seq.append(x)
return seq
The update step.
def newton_update(x, f, df):
return x - f(x)/df(x)
The iteration.
def iterate(x, func):
while True:
yield x
x = func(x)
Truncate to length 10 and store in a list.
def take10(seq):
return list(islice(seq, 0, 10))
Make the infinte Newton sequence.
def newton_seq(x, f, df):
update = partial(newton_update, f=f, df=df)
yield from iterate(x, update)
Truncate and make into a list.
def newton_same_as_old(x0, f, df):
return take10(newton_seq(x0, f, df))
Code should be open for extension, but closed to modification.
(Second in the SOLID principles.)
Multidimesional Newton's?
Broyden's method?
To use an $f$ tolarance?
To use a Cauchy tolarance?
To have a maximum length?
1D secant method?
For you...
Resources
Slides: shawsa.github.io