Deep Dojo

Python Notes

The notes below are not for the expert. To the contrary, they’re for getting acquainted (or reacquainted) with the language. It’s something I keep around for that purpose. I wrote the first draft in 2004. The the second draft was collated in 2013 using Python: Essential Reference.

Just enough syntax to get you started. Many details will look familiar to Swift programmers.

Basics

# Comments are prefixed with a pound.
string = '# except inside string literals'

Python source files have a .py suffix.

Delimiters

Semicolons can separate statements.

a = 1; b = 45.0;

However, new lines are preferred.

a = 1
b = 45.0

Indentation delimits code into blocks.

index = 0

while index < 5:
    print(index)
    index += 1

The amount of indentation for a block must be consistent. Tabs are first converted to spaces. Use of tabs is discouraged.

pass must be used for empty blocks.

if a > b:
    pass   # do nothing
elif a == b:
    result = 0

Variables

  • Have no type.
  • Are merely labels that refer to objects (which do have type).
  • Assign None to disconnect a variable.
  • Use del() to delete an object.

Strings

'foo' is equivalent to "foo". Each quote type conveniently demarcates the other as content.

dialog = 'He asked, "Are you talking to me?"'

Adjacent strings concatenate.

>>> 'hello' ' world'
'hello world'

>>> 'hello' + ' world'
'hello world'

Triple quotes span multiple lines.

dialog = '''He stood in front of the mirror.
Glaring, he asked again.
"Are you talking to me?"
'''

Collection Basics

Slices

s = 'hello world'
first_word = s[0:5]
second_word = s[6:]

Lists

>>> empty_list = []

>>> my_list = [1, 'dog', ['a', 'b', 'c', ['d', 'e', 'f']]]
>>> len(my_list)
3
>>> my_list[2][3][2]
'f'

A tuple is an immutable collection.

a = (1, 2, 3)
b = (7,)

Python is smart enough to parse some tuples without parenthesis.

c = 1, 2, 3
d = 7,

Iteration

for item in my_list:
    process(item)

negated_values = [-v for v in values]

A range can synthesize a list. The end of a range points one past the last element. (In Python 2, a range is a list.)

# my_range = range(start, end, stride)

>>> list(range(5))
[0, 1, 2, 3, 4]

>>> list(range(2, 5))
[2, 3, 4]

>>> list(range(3, 0 -2))
[3, 1]

Dictionaries

account = {'username': 'joe', 'ID': 500}
name = account['username']

Constant objects, including numbers and tuples, may be used as dictionary keys.

>>> list(account.keys())
['username', 'ID']

>>> del account['username']

Basic Code

Functions

Multiple values can be returned in a tuple.

def divide(lhs, rhs):
    quotient = int(lhs / rhs)
    remainder = lhs - quotient * rhs
    return (quotient, remainder)

Python resolves default values as well as argument labels.

def connect(hostname, port, timeout=300):
    # implementation...

connect('www.python.org', 80)
connect(port=80, hostname='www.python.org')

Function variables have local scope unless modified.

dog = 'fido'

def foo():
    # Refer to the dog outside of this function.
    global dog
    dog = 'rex'

Classes

The first argument of an instance method always refers to an instance of the class. The convention is to call this argument self.

class Dog:

    def __init__(self, name):
        self.name = name

    def bark(self):
        print(self.name + ': woof woof')

Error Handling

Exceptions are raised in Python.

raise RuntimeError('Error message...')

Exceptions can be caught with try and except.

Packaging

A module lets you assemble a name space.

# file: div.py
def divide( lhs, rhs ):
    quotient = lhs / rhs
    remainder = lhs - quotient
    return ( quotient, remainder )

--

# Define div.divide()
import div

# Define foo.divide()
import div as foo

# Define divide() in current name space.
from div import divide

# Import all div stuff into the current name space.
from div import *

# What's in the div module anyway?
import div
dir(div)

Conventions

Lines

Newlines terminate a statement unless continued with a backslash.

a = 1 + 2 + \
3 + 4

However, anything within (), [], {} or triple-quotes does not require a continuation character to span multiple lines. Dictionaries, tuples and lists will span multiple lines automatically.

Identifiers

Must start with [a-zA-Z_] and may then include [a-zA-Z0-9_]. Identifiers are case sensitive.

Reserved Words

and, as, assert, break, class, continue, def, del, elif, else,
except, exec, finally, for, from, global, if, import, in, is, lambda
not, or, pass, print, raise, return, try, while, with, yield

Doc Comments

A string is a documentation string if it is the first statement within a module, class or function definition.

def foo():
    """Foo is not bar.

    More details...

    Even more details...
    """
    # implementation...

Type

The null for Python is None.

Every bit of data in Python is an object. An object has type, value and identity.

# a and b have the same type.
a = [4]
b = [5]

# a and b have the same type and value.
a = [4]
b = [4]

# a and b have the same type, value and identity.
a = [4]
b = a

Python can hash non-mutable objects.

# a and b have the same type, value _and_ identity.
a = 4
b = 4

There are tests for type, value and identity.

if type(a) is type(b):
    print('a and b are the same type.')

if a == b:
    print('a and b are the same value.')

if a is b:
    print('a and b are the same object.')

Variables are merely labels for objects. The objects themselves are reference counted.

# Increase reference count for 3.4
a = 3.4

# Increase reference count for 3.4
b = a

# Decrease reference count for 3.4
del a

# Decrease reference count for 3.4
b = 5.6

A slice makes a shallow copy.

a = [1, 2, [3, 4]]

# b is not a.
# b _does_ contain the same objects as a.
b = a[:]

A deep copy requires more than slicing.

import copy
a = [1, 2, [3, 4]]

# b is not a.
# b does _not_ contain _all_ of the same objects as a.
b = copy.deepcopy(a)

Sequences

Includes strings, lists and tuples. In addition to slicing and deletion, sequences also support queries.

len(s)
min(s)
max(s)

A list is a sequence with additional instance methods.

count(), index(),
append(), insert(), pop(),
reverse(), sort()

Strings are sequences with even more instance methods:

capitalize(), center(), count(), endswith(), expandtabs(),
find(), index(),
isalnum(), isalpha(), isdigit(), islower(),
isspace(), istitle(), isupper(),
join(),
ljust(), lower(), lstrip(), replace(), rfind(), rindex(), rjust(),
rstrip(), split(), splitlines(), startswith(), strip(),
swapcase(), title(), translate(), upper()

Additional Resources

Python Version

As of 2017, macOS ships with Python 2.7. It’s the version used by coremltools.

You can also install Python 3 on your Mac.

Package Management

pip and virtualenv are your friends.

“One of the hurdles that new Python developers have to get over is understanding the Python packaging ecosystem.”

Jamie Matthews

Style

Once you feel more familiar with the language, the PEP 8 style guide is an effective shortcut for making your code more pythonic. For a more daring alternative, take the executable version of the style guide and integrate it into your Python build.