NOTE: Lectures 8 and 9 were done with substitute instructors. Professor Richards wrote this notebook, so it may not be exactly as was covered with the substitutes.¶

In [3]:
import math
import typing

def leibnizPiCallback(cb: typing.Callable) -> float:
    """
    Returns a Leibniz approximation of pi. Use the callback to indicate when to
    stop: cb will be called with the current approximation, and should return
    True to tell this function to stop.
    """
    pi = 0.0
    sign = 1
    den = 1
    
    while True:
        pi = pi + sign*4/den
        if cb(pi):
            return pi
        sign = sign * -1
        den = den + 2
        
def closeEnoughPi(approx: float) -> bool:
    """
    Returns True if approx is close enough to pi, False otherwise.
    """
    return abs(approx - math.pi) < 0.000001

print(leibnizPiCallback(closeEnoughPi))
3.1415936535887745
In [4]:
for c in "Hello, world!":
    print(c)
H
e
l
l
o
,
 
w
o
r
l
d
!
In [5]:
print("Hello, world!"[1])
print(range(1, 10)[2])
e
3
In [6]:
s = "Hello, world!"
for i in range(len(s)):
    print("s at", i, "is", s[i])
s at 0 is H
s at 1 is e
s at 2 is l
s at 3 is l
s at 4 is o
s at 5 is ,
s at 6 is  
s at 7 is w
s at 8 is o
s at 9 is r
s at 10 is l
s at 11 is d
s at 12 is !
In [7]:
x = "Hello, world!"
x[1] = "u"
<cell>2: error: Unsupported target for indexed assignment ("str")  [index]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [7], in <cell line: 2>()
      1 x = "Hello, world!"
----> 2 x[1] = "u"

TypeError: 'str' object does not support item assignment
In [8]:
x = [2, 4, 6, 0, 1]
print(x[2])
6
In [9]:
def averageOf(l: list[float]) -> float:
    """
    Returns the average (mean) value in the list l.
    """
    sum = 0.0
    for val in l:
        sum = sum + val
    return sum / len(l)

print(averageOf([2, 4, 6, 0, 1]))
2.6
In [10]:
def contains(
    haystack: typing.Sequence,
    needle: typing.Any
) -> bool:
    """
    Returns True if the value needle is in the sequence haystack, False otherwise.
    """
    for val in haystack:
        if val == needle:
            return True
    return False

print("Is 6 in 24601?", contains([2, 4, 6, 0, 1], 6))
print("Is z in hello world?", contains("Hello, world!", "z"))
Is 6 in 24601? True
Is z in hello world? False
In [11]:
x = [2, 4, 6, 0, 1]
print(x)
x[1] = 8
print(x)
[2, 4, 6, 0, 1]
[2, 8, 6, 0, 1]
In [13]:
def runningAverage(l: list[float]) -> float:
    """
    Replaces the values in the list l with the running average, and returns the
    average value in the (original) list.
    """
    sum = 0.0
    for idx in range(len(l)):
        sum = sum + l[idx]
        l[idx] = sum / (idx+1)
    return sum / len(l)

x = [2.0, 4, 6, 0, 1]
print("The average of 2,4,6,0,1 is", runningAverage(x))
print("The running averages at each point are", x)
The average of 2,4,6,0,1 is 2.6
The running averages at each point are [2.0, 3.0, 4.0, 3.0, 2.6]
In [14]:
x = [2, 4, 6, 0, 1]
y = x
x[1] = 8
print(y[1])
for i in y:
    i = 0
print(y[1])
8
8
In [17]:
def squareList(l: list[float]) -> None:
    """
    Squares every value in the list l.
    """
    for i in range(len(l)):
        l[i] = l[i]**2
        
x: list[float] = [2, 4, 6, 0, 1]
squareList(x)
print(x)
[4, 16, 36, 0, 1]
In [20]:
def removeFactorsOfTwo(l: list[int]) -> None:
    """
    Removes the factors of two from each number in the list l, while keeping
    all other factors intact.
    """
    for idx in range(len(l)):
        val = l[idx]
        while val%2 == 0 and val > 1:
            val = val // 2
        l[idx] = val
        
y = [8, 6, 7, 5, 3, 0, 9]
removeFactorsOfTwo(y)
print(y)
[1, 3, 7, 5, 3, 0, 9]

(L9 starts approximately here)¶

In [22]:
def reverse(lst: list) -> None:
    """
    Reverses the list lst in place.
    """
    for idx in range(0, len(lst)//2):
        tmp = lst[idx]
        lst[idx] = lst[-1-idx]
        lst[-1-idx] = tmp
        
x = [2, 4, 6, 0, 1]
reverse(x)
print(x)
x = [8, 6, 7, 5, 3, 0, 9]
reverse(x)
print(x)
reverse(x)
print(x)
[1, 0, 6, 4, 2]
[9, 0, 3, 5, 7, 6, 8]
[8, 6, 7, 5, 3, 0, 9]
In [23]:
def greatest(lst: list[float]) -> float:
    """
    Returns the greatest value in the list lst.
    """
    assert len(lst) > 0, "No greatest in an empty list"
    r = lst[0] # Don't start with 0!
    for val in lst:
        if val > r:
            r = val
    return r

print(greatest([3, 14, 15, 92, 65, 35, 89, 79, 32]))
92
In [26]:
e = [2, 6, 8]
print(e)
e.insert(1, 4)
print(e)
e.insert(0, 0)
print(e)
e.append(10)
print(e)
[2, 6, 8]
[2, 4, 6, 8]
[0, 2, 4, 6, 8]
[0, 2, 4, 6, 8, 10]
In [27]:
def divisors(x: int, y: int) -> list[int]:
    """
    Returns all the common divisors of x and y.
    """
    r = []
    i = 1
    while i <= x and i <= y:
        if x%i == 0 and y%i == 0:
            r.append(i)
        i = i + 1
    return r

print(divisors(44100, 48000))
[1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 25, 30, 50, 60, 75, 100, 150, 300]
In [28]:
e = [0, 2, 4, 6, 8]
print(e)
e.pop(0)
print(e)
e.pop()
print(e)
[0, 2, 4, 6, 8]
[2, 4, 6, 8]
[2, 4, 6]