Today: lambda warmup, modules 1.0, wordcount module, HW7 preview, bluescreen art contest

Lambda Warmup

Do this in the interpreter

Suppose have a list of strings. How to sort these into increasing order by length? What 1-liner / lambda will pull out the string with the largest length?

>>> strs = ['apple', 'glaze donut', 'pear', 'banana']
>>> 

Solution

>>> # project out len(s) for each string
>>> sorted(strs, key=lambda s: len(s))
['pear', 'apple', 'banana', 'glaze donut']
>>>
>>> # max pulls out largest one
>>> max(strs, key=lambda s: len(s))
'glaze donut'

Modules

Standard Modules - import math

>>> import math
>>> math.sqrt(2)  # call sqrt() fn
1.4142135623730951
>>> math.sqrt

>>> 
>>> math.log(10)
2.302585092994046
>>> math.pi       # constants in module too
3.141592653589793

Restart interpreter without the import, see common error:

>>> # quit and restart interpreter
>>> math.sqrt(2)  # OOPS forgot the import
Traceback (most recent call last):
NameError: name 'math' is not defined
>>>
>>> import math
>>> math.sqrt(2)  # now it works
1.4142135623730951

Hacker: Use dir() and help()

>>> import math
>>> dir(math)
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']
>>>
>>> help(math.sqrt)
Help on built-in function sqrt in module math:

sqrt(x, /)
    Return the square root of x.
>>>
>>> help(math.cos)
Help on built-in function cos in module math:

cos(x, /)
    Return the cosine of x (measured in radians).

Module Recap

wordcount.py Is a Module

>>> # Run interpreter in wordcount directory
>>> import wordcount
>>>
>>> wordcount.read_counts('test1.txt')
{'a': 2, 'b': 2}

dir() and help() work on wordcount Too.

>>> dir(wordcount)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'clean', 'main', 'print_counts', 'print_top', 'read_counts', 'sys']
>>> 
>>> help(wordcount.read_counts)

Help on function read_counts in module wordcount:

read_counts(filename)
    Given filename, reads its text, splits it into words.
    Returns a "counts" dict where each word
    ...

Two Ways of wordcount.py

How Does Python Know To Run main()?

Typical last 2 lines of .py file:

if __name__ == '__main__':
    main()

Experiment: Put these lines at end of wordcount.py. Then try running wordcount from command line, and loading it in interpreter.

if __name__ == '__main__':
    print("I feel like running main()")
    main()
else:
    print("Not running main()")

Design Idea: Easy Things Should be Easy

Design idea: doing the ordinary thing should be easy, not require thought. Doing something hard should be possible, but may require work.

This __name__ business seems a weak point in Python's design. It is not great that every vanilla python program has to carry around these 2 obscure looking lines. There should be a less obscure way of getting the default behavior that 99% of python programs want.

Demo HW7 Baby Graphics

Demo HW7 Ghost

Bluescreen Art Contest (optional!)

> bluescreen-monkey