class: inverse # The Zen ```python >>> import this ``` ``` The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! ``` --- # In Python, everything is an _object_ Objects have a well-defined type and can be assigned to variables. Every object has an **identity**, a **type** and a **value**. - We've seen examples of built-in objects with types `str`, `float`, `dict`, etc. But functions, file handles, and even `None` are objects too. - e.g., we can pass the builtin function `int` as an argument to another builtin function, `map` ```python >>> map(int, [1.15, 2.08, 3.14, 4.89]) [1, 2, 3, 4] ``` - Many objects have accessible properties called _attributes_. - attributes are accessed using dot `.` notation - Many objects also have callable attributes _methods_. - these are special functions that are bound to objects - We can create our own custom objects by "deriving" or "subclassing" them from builtins. - this is called "object-oriented programming" (more later) --- # Batteries included: [The Standard Library](https://docs.python.org/3/library/) Some useful modules: - `sys`: python path, stdin, stdout, other utilities - `os`: miscellaneous operating system interfaces - `re`: regular expressions - `collections`: more data structures! - `heapq`: priority queue algorithms - `itertools`: functions to create efficient iterators - `math`: mathematical functions - `json`: read/write JSON formatted data - `unittest`: unit testing framework --- class: center, middle # Namespaces, modules, classes --- # Modules A way to put definitions in a file and use them in a program or in an interactive instance of the interpreter. - A module is a file (with the suffix `.py`) containing Python definitions and statements. A module can contain executable statements as well as function definitions and can import other modules. - Definitions from a module can be imported into other modules or into your script. - There are also hierarchical modules, called "packages", which are directories containing a file called `__init__.py`. - `dir()` function --- # Importing ```python import foo foo.bar() from foo import bar bar() from foo import bar, baz, spam, eggs from foo import * # bad practice, use sparingly! ``` --- # Scripts Every `.py` file can be imported as a module. In particular, when you execute a Python file as a script ```bash $ python my_script.py ``` the code in the module will be executed, just as if you imported it, but with the `__name__` attribute of the module set to `"__main__"`. As a result, the
`if __name__=='__main__'`
idiom lets makes a Python file usable both as a module and script: ```python # --- fibo.py --- # Fibonacci numbers module def fib(n): # write Fibonacci series up to n a, b = 0, 1 while b < n: print(b, end=' ') a, b = b, a+b print() if __name__ == "__main__": import sys fib(int(sys.argv[1])) # run the fib function on command line input ``` --- # Namespaces: a honking good idea A _namespace_ is a mapping from names to objects. Examples: - the set of built-in names (function names and exception names) - the global names in a module - the local names in a function invocation - the attribute names of an object --- # Variable scope (LEGB rule) A _scope_ is a textual region of a Python program where a namespace is directly accessible. .right-column[
] 1\. **L** local names assigned in a function (using `def` or `lambda`) and not declared global in that function. 2\. **E** enclosing function names in the local scope of any and all enclosing functions, from inner to outer. 3\. **G** global (module-level) names assigned at the top-level of a module file, or declared global in a function within the file using the `global` keyword 4\. **B** builtin names preassigned as built-in names module, e.g.: `open`, `range`, `SyntaxError`, ... --- Consider the following code: ```python a_var = 'global value' def outer(): a_var = 'enclosed value' def inner(): a_var = 'local value' print(a_var) inner() outer() ``` What's the output ??? -
source: http://sebastianraschka.com/Articles/2014_python_scope_and_namespaces.html
--- # [Classes](https://docs.python.org/3.5/tutorial/classes.html) User-defined data types! - Classes are the blueprints or definitions for creating (instantiating) new objects - Objects (class instances) have both data and behavior (methods). - Objects are *mutable*. Their attributes are accessible using dot notation. --- # Class definition ``` class ClassName(
):
. . .
``` ```python class Point: """ Point class represents and manipulates x,y coords. """ def __init__(self): """ Create a new point at the origin """ self.x = 0 self.y = 0 p = Point() # Instantiate an object of type Point q = Point() # Make a second point print(p.x, p.y, q.x, q.y) # Each point object has its own x and y ``` --- # Instantiation and `__init__` The `__init__` method is the class initializer or "constructor". ```python class Point: """ Point class represents and manipulates x,y coords. """ def __init__(self, x=0, y=0): """ Create a new point at x, y """ self.x = x self.y = y p = Point(5, 6) ``` --- # Attributes and methods ```python class Point: """ Create a new Point, at coordinates x, y """ def __init__(self, x=0, y=0): """ Create a new point at x, y """ self.x = x self.y = y def distance_from_origin(self): """ Compute my distance from the origin """ return ((self.x ** 2) + (self.y ** 2)) ** 0.5 ``` --- # Inheritance and polymorphism ```python class Animal(object): def __init__(self, name): self.name = name def speak(self): raise NotImplementedError def sleep(self): print("ZzzzZzzzZZzzzz...") class Dog(Animal): def speak(self): print("Woof!") class Cat(Animal): def speak(self): print("Meow!") ``` --- # Sidenote: underscore conventions - `_foo`: non-public, use me at your own risk - `__foo`: private, name gets mangled - `__foo__`: usually builtin special attributes or names used to fulfill protocols (e.g., iteration). These are sometimes called [magic methods](http://www.rafekettler.com/magicmethods.html). --- # Exceptions are classes too! ```python class PageNotFoundError(Exception): pass ... if page not in pages: raise PageNotFoundError ``` --- class: center, middle # PyGame --- # What is PyGame? - PyGame is a wrapper around the Simple DirectMedia Layer (SDL) library, written in C, which provides access to your computer's audio, keyboard, mouse, joystick, and graphics hardware. - SDL, in turn is a wrapper around many of your Operating System's low-level graphics and multimedia functionality. .center[
] --- # The game loop
.center[
]
.small[http://openbookproject.net/thinkcs/python/english3e/pygame.html]
Pygame **polls** the system for events. Then we update any objects that need updating and redraw the current state of the game. --- # A simple physics engine .center[
]