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
- "module" - unit of code to use, "library"
- Every module has a name, e.g. "math"
- Module contains lots of functions, solving common problems
- Modern coding:
1. Part you build on code from a module
2. Part you write custom
Standard Modules - import math
- Python comes with "standard" modules
- Standard modules are installed when Python is installed, so no extra step required
- e.g. the "math" module - mathematics
- e.g. the "sys" module - interface with operating system
- import module by name
- Use dot to refer to functions etc. in the module
math.sqrt(2) - function call
math.pi - pi constant within math
- Shown here in interpreter, but works in .py too
- Common error: forgetting to do the import
- Aside: there are other import forms, but this name/dot form is the most important
>>> 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()
- Feel like a hacker, use dir() and help() on module
- In the interpreter >>>
dir(module) - shows a list of all the defs in the module
help(module.fn) - shows some help text for that function
>>> 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
- What's a module?
- Has a name
- Holds lots of functions
i.e. "library" of functions
- Use
import math to bring it in
- Use
math.sqrt(5) syntax to call a function in a module
wordcount.py Is a Module
- Suppose you have built some useful functions
- Someone else in your lab wants to use them....
Them pasting in their own copy is not ideal
- What does a module contain?
- We have wordcount.py
- python3 wordcount.py - runs main()
- wordcount.py is also a module named just "wordcount"
- Think of all the defs in wordcount: read_counts(), clean(), print_counts(),
- import works on wordcount (in the same directory)
- Access functions as module.xxx just like usual
- Run python interpreter in wordcount directory to try this
- Try importing wordcount, calling the read_counts() function
- Call wordcount.clean()
>>> # Run interpreter in wordcount directory
>>> import wordcount
>>>
>>> wordcount.read_counts('test1.txt')
{'a': 2, 'b': 2}
- A module/file contains many defs
- Can import a module/file, call its defs:
- module.fn_name()
- Style: for a function to be usable from another module...
it should take in data as parameters and return a value
i.e. black box style
we've done this all along, see now the bigger picture
- HW7 babygraphics:
treat babynames.py as a module
import babynames
call babynames.read_files() etc.
dir() and help() work on wordcount Too.
- dir() and help() work too
- See where the """Pydoc""" goes!
>>> 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
- Two ways this file can be used
- 1.
python3 wordcount.py poem.txt
load up all the wordcount.py code
run main() ... it runs all the functions
- 2. Some code does
import wordcount
In this case:
Load all the wordcount.py code
do not run main
Module sits there
Waiting for a call like wordcount.read_counts() to happen
- How are these two cases distinguished?
- (1) is common BTW, (2) is rare but should work
How Does Python Know To Run main()?
- There is a special variable
__name__
- Python aside: when a name begins with underbars
Signifies an internal detail that normal code should not mess with
- When __name__ has the special value __main__
It means we have case (1), we are supposed to run main()
- This is why there's that crazy if-statement at the bottom of the file!
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
- It's just calling your babynames.xxx functions
- Code in here draws lines, colors
Demo HW7 Ghost
- Look at image series - think about outlier
clock tower
monster
- Algorithmic Look At Pixels
Bluescreen Art Contest (optional!)
- We'll have optional HW7c art project you can do for fun
Slight extra credit, not affecting curve
Really just for fun after you're done with HW7
Art show in class, prizes
- Recall - Bluescreen algorithm
- 1. "front" strategy
- Detect blue pixels - average technique
- Replace blue pixels in image with background pixels
- More details Monday (do HW7 first)
- Demo here - comment out the pixel.red = xxx lines to see original image
>
bluescreen-monkey