SAISOFT PYT-PR: Session 10

What Have We Learned?


In [1]:
lessons = {
    "1": "Python is part of a bigger ecosystem (example: Jupyter Notebooks).",
    "2": "Batteries Included refers to the well-stocked standard library.",
    "3": "Built-ins inside __builtins__ include the basic types such as...",
    "4": "__ribs__ == special names == magic methods (but not all are methods).",
    "5": "3rd Party Python is where a lot of the action is!",
    "6": "'Python fits your brain' means it gets out of your way once you learn it."
}

important_types = [{'Numeric': ["int", "float", "Decimal", "Fraction", "complex"],
                    'Collections': [{"Sequences": ["list", "range", "tuple"],
                                      "Mappings": ['dict', 'set']}],
                    'Descriptors': ['property']}, 
                   {'Other types': ['function', 'class', 'generator']}]

In [2]:
for key, value in lessons.items():  # dict method to return all key:value pairs
    print("{}.: {}".format(key, value), file=None) # this could be HTML to a file
    if key == "3":
        print()
        for the_type in important_types[0]['Numeric']:
            print(the_type)
        for the_type in important_types[0]['Collections'][0]['Sequences']:
            print(the_type)  
        for the_type in important_types[0]['Collections'][0]['Mappings']:
            print(the_type)
        print()


1.: Python is part of a bigger ecosystem (example: Jupyter Notebooks).
2.: Batteries Included refers to the well-stocked standard library.
3.: Built-ins inside __builtins__ include the basic types such as...

int
float
Decimal
Fraction
complex
list
range
tuple
dict
set

4.: __ribs__ == special names == magic methods (but not all are methods).
5.: 3rd Party Python is where a lot of the action is!
6.: 'Python fits your brain' means it gets out of your way once you learn it.

Continue to "doodle and daydream" as you find the time. Think of ways to describe your day as a Python program. Remember the story of The Car that Would Not Start.

Run this a few times to see the different possible workflows.


In [3]:
import random
class BatteryDead(Exception):
    pass
class IgnitionKeyBroken(Exception):
    pass

class Car:
    
    def start(self):
        as_luck_would_have_it = random.randint(0,10)
        if as_luck_would_have_it == 10:
            raise BatteryDead
        elif as_luck_would_have_it == 0:
            raise IgnitionKeyBroken
        print("Car starts!")

try:
    # might not work
    my_car = Car()
    my_car.start()
except BatteryDead:
    print("Oops, need to charge battery")
except IgnitionKeyBroken:
    print("Oops, your key just snapped")


Oops, need to charge battery

We also learned about decorator syntax. Using a decorator, we're able to use a callable as an input to an object that provides a proxy output, likewise callable by the same name.


In [4]:
from functools import wraps

def decorator(f):
    @wraps(f)
    def proxy(x):
        # proxy
        print("Look at me!")
        return f(x)
    return proxy

@decorator
def Sqr(x):
    """Square Dancer"""
    return x * x

In [5]:
Sqr(10)


Look at me!
Out[5]:
100

@wraps forwards the __doctstring__ and __name__ of the incoming f argument to the proxy being wrapped.

LAB:

Try commenting out the line with @wraps on it and checking the __doctstring__ and __name__ of Sqr again.

  • Comment out @wraps
  • re-run the cell containing the two function definitions
  • re-run the cell below, and not changes
  • change it back

In [6]:
help(Sqr)


Help on function Sqr in module __main__:

Sqr(x)
    Square Dancer