Python

A readable, elegant programming language

Created by Joshua Nelson with reveal.js

Why Python?

  • Concise but readable
  • List/Map/Set literals
  • File IO is easy
  • Operator overloading
  • Readable with statement (equivalent of try-with-resources from java)
  • Batteries-included standard library
  • Extensive packages

Concise but readable

import os

BASE = "<html><body>%s</body></html>"
SLIDE_FORMAT = """
<section data-markdown>
    <textarea data-template>%s</textarea>
</section>
"""
SLIDES = 'slides'

content = ""
for slide in os.listdir(SLIDES):
    with open(os.path.join(SLIDES, slide)) as markdown:
        content += SLIDE_FORMAT % markdown.read()

print(BASE % content)

Builtin interpreter

$ python
Python 3.6.6 (default, Sep 12 2018, 18:26:19)
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("hi")
hi
>>> variable = "hi"
>>> print(variable)
hi
>>> print(variable + " there")
hi there

List/Map/Set literals

>>> l = ['a', 'b', 'c']
>>> print(l[2])
c
>>> m = {"one": 1, "twelve": 12, "three hundred": 300}
>>> print(m["one"])
1
>>> s = {"a", "a", "c"}
>>> print(s)
{'c', 'a'}

Note: in python, maps are called dictionaries

Duck Typing

Methods and fields are looked up at runtime. This is the main reason python is so slow.

Duck Typing: an example

>>> def try_remove_one(x):
...     x.remove(1)
...     print(x)
...
>>> try_remove_one([1, 2, 3])
[2, 3]
>>> try_remove_one({1, 2, 3})
{2, 3}
>>> try_remove_one({1: 2, 3: 4})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in try_remove_one
AttributeError: 'dict' object has no attribute 'remove'
  

Syntax differences from C/Java

  • Whitespace is significant
  • Semicolons are optional
  • Braces are banned
  • Only for-each loops

Whitespace is significant

  • Indentation determines blocks
  • >>> x = 0
    >>> while x < 10:
    ...     print(x)
    ...     x += 2
    ...
    0
    2
    4
    6
    8
  • Mixing tabs and spaces is an error

Braces are banned

>>> from __future__ import braces
  File "<stdin>", line 1
SyntaxError: not a chance

Only for-each loops

>>> for x in [1.3, 4.2, 41.65]:
...     print(x * 3.5)
...
4.55
14.700000000000001
145.775

How to do a traditional for-loop? Use ranges

>>> l = []
>>> for i in range(10):
...     l.append(i + 1)
...
>>> l
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Usually you would use enumerate instead

>>> for i, element in enumerate(["a", "b", "c"]):
...     print(i, element)
...
0 a
1 b
2 c

File IO

Standard input/output

>>> print("Hello " + input("What is your name? "))
What is your name? josh
Hello josh

File IO

Files

>>> file_object = open('test.txt')
>>> print(file_object.read())
this is test content
more content

>>> file_object.close()

File IO

Absolute paths

>>> import os
>>> os.path.abspath('test.txt')
'/home/joshua/Documents/Programming/ACM/spring-2019/python/test.txt'     

Tuples

Tuples are the same as lists, but can't be modified

>>> t = (1, 2, 3)
>>> t[0] = 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment  

Returning multiple values returns a tuple

>>> def f(x):
...     return x + 1, x + 2
...
>>> print(f(0))
(1, 2) 

List comprehensions

>>> [x for x in range(10) if x % 2]

is equivalent to

>>> l = []
>>> for x in range(10):
...     if x % 2:
...             l.append(x)
...
>>> l
[1, 3, 5, 7, 9]

This works with sets, too

Dict comprehensions

>>> {n: n**2 for n in range(5)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

is equivalent to

>>> d = {}
>>> for n in range(5):
...     d[n] = n**2
...
>>> d
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Imports

The things you import are called modules

>>> import os
>>> os
<module 'os' from '/usr/lib/python3.6/os.py'>

Import Aliases

>>> import re as regex

is equivalent to

>>> import re
>>> regex = re
>>> del re

Importing without a prefix

>>> from os import path

is equivalent to

>>> import os
>>> path = os.path
>>> del os
>>> path
<module 'posixpath' from '/usr/lib/python3.6/posixpath.py'>

Wildcard imports

This is the same as wildcard imports for everything in the module

>>> from os import *
>>> path
<module 'posixpath' from '/usr/lib/python3.6/posixpath.py'>

Don't do this.

String manipulation

  • Concatenation and tokenizing
  • String formatting

Splitting

>>> 'hi there\nyou'.split()
['hi', 'there', 'you']
>>> 'hi there\nyou'.split(' ')
['hi', 'there\nyou']
>>> 'hi there\nyou'.split('\n')
['hi there', 'you']

Concatenation

>>> ' '.join(["one", "two", "three"])
'one two three'

Both at once

>>> ' '.join("one two three".split())
'one two three'

String formatting

printf formatting

>>> '%f is %d as an integer' % (2.0, 2.0)
'2.000000 is 2 as an integer'

Note: this breaks for tuples

>>> tup = (1, 32, 51)
>>> '%s' % tup
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting

str.format

>>> '{0} is {0:.0f} as an integer'.format(2.0)
'2.0 is 2 as an integer'
>>> '{}'.format(tup)
'(1, 32, 51)'

Arrays

[0,1,2,3,4][start:stop:step]

Arrays - negative indexing

>>> a = [0,1,2,3,4]
>>> a[-1]
4
>>> a[-4]
1
>>> a[-6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

Arrays - splicing

a[start:stop]

>>> [0,1,2,3,4][1:]
[1, 2, 3, 4]
>>> [0,1,2,3,4][:1]
[0]
>>> [0,1,2,3,4][1:3]
[1, 2]
>>> [0,1,2,3,4][3:1]
[]

Arrays - splicing steps

a[start:stop:step]

>>> [0,1,2,3,4][::2]
[0, 2, 4]
>>> [0,1,2,3,4][::-1]
[4, 3, 2, 1, 0]
>>> [0,1,2,3,4][1::-1]
[1, 0]
>>> [0,1,2,3,4][4::-1]
[4, 3, 2, 1, 0]
>>> [0,1,2,3,4][:2:-1]
[4,3]
>>> [0,1,2,3,4][::-2]
[4, 2, 0]

Classes

  • Duck Typing
  • Operator overloading
  • self
  • Multiple inheritance

Operator overloading

Self

this from Java is an explicit parameter, called self by tradition

When you add a method, you have to remember to add a self parameter.

>>> class c:
...     def __init__(self, x):
...             self.x = x
...
>>> c(4)
<__main__.c object at 0x7f2563291390>
>>> c(4).x
4

Self: everything is a static function

>>> str.format('{} and {}', 'a', 'b')
'a and b'
>>> '{} and {}'.format('a', 'b')
'a and b'

Multiple inheritance

It's ... complicated.

Context Managers

Also known as the "with" statement

>>> with open('test.txt') as file_object:
...     print(file_object.read())
...
this is test content
more content

is equivalent to

>>> file_object = open('test.txt').__enter__()
>>> print(file_object.read())
this is test content
more content

>>> file_object.__exit__()

which in turn is equivalent to

>>> file_object = open('test.txt')
>>> print(file_object.read())
this is test content
more content

>>> file_object.close()