ES 26 Python Reference Sheet
ES 26 Class Rules
ES 26 Lecture Slides
Linux terminal
Command line
kevin@kevinsogo:~/foo/bar$
kevin— user namekevinsogo— computer name~/foo/bar— current folder
USERNAME@COMPUTERNAME:CURRENTFOLDER$
Basic commands
ls— list contents of current directorycd FOLDERNAME— change directory toFOLDERNAMEmkdir FOLDERNAME— make new directory namedFOLDERNAMEtouch FILENAME— make new file namedFILENAMEpython3 FILENAME— runFILENAMEas a Python programpython3— run Python in interactive modesubl NAME— openNAMEin Sublime Textsubl— open Sublime Text
Some special syntax
~— home folder (/home/USERNAME)..— parent folder.— current folder
Recommended Visual Studio Code Settings
- Editor: Render Whitespace: set to
all - Files: Auto Save: set to
afterDelay - Files: Auto Save Delay: set to a value less than 5000
Python
Integers (int)
- ...,
-3,-2,-1,0,1,2,3, ...
Conversion
int(x)int(5) == 5int('5') == 5int(True) == 1int(False) == 0
Operations
+,-,*— arithmetic2 + 3 * 4 - 5 == 9
/— division (producesfloats; be careful!)15 / 6 == 2.512 / 6 == 2.0 # float!
//— floor division15 // 6 == 212 // 6 == 2-1 // 6 == -1
%— modulo/remainder15 % 6 == 312 % 6 == 0-1 % 6 == 5
**— power2**3 == 8
==,!=,<,>,<=,>=— comparison (see below)- Division Theorem — the following is always true if
b != 0a == (a // b) * b + (a % b)
Strings (str)
- delimited by single quotes or double quotes
'hi' == "hi"
- escape with
\"a\\b\"c"
Conversion
- almost anything can be converted to
strviastr()str(5) == "5"str(('1', 2)) == "('1', 2)"
Operations
+— concatenate strings"abc" + "def" == "abcdef"
*— replicate string"hi" * 4 == "hihihihi"
s in t— substring check"nan" in "banana"
t.index(s)— substring location (leftmost)"banana".index("na") == 2
s.strip()— leading and trailing whitespace (spaces, tabs, newlines) all removed" a b c ".strip() == "a b c"
s[i]— indexing- get element at index
i s[0]is the first elements[-1]is the last element- indexing starts at
0 - negative indices start at the back
"banana"[2] == "banana"[-2] == "n"
- get element at index
s[i:j]— slicing- substring from index
iinclusive to indexjexclusive "banana"[1:4] == "ana""banana"[-4:] == "nana""banana"[2:2] == "banana"[3:2] == ""
- substring from index
s[i:j:k]— slicing with step sizek"banana"[2:4:2] == "n""banana"[2:5:2] == "nn""banana"[1::2] == "aaa""banana"[::-1] == "ananab"
len()— lengthlen("banana") == 6
==,!=,<,>,<=,>=— comparison (see below).join— join to single string'--'.join(("ab", "cd", "efg")) == "ab--cd--efg"
.split— split string tolistby whitespace" Let It Be ".split() == ['Let', 'It', 'Be']
Booleans (bool)
- Only two values:
TrueandFalse
Conversion
bool(x)convertsxtoTrueifxis, in some sense, "nonempty" or "nontrivial"- for
ints andfloats,bool(x)isTrueiffxis nonzero - for
strs andtuples,bool(x)isTrueiffxis nonempty bool("") is Falsebool(0) is Falsebool(None) is Falsebool(()) is Falsebool(1) is Truebool(5) is Truebool(-1) is Truebool("hi") is Truebool("True") is Truebool("False") is Truebool((1, 2)) is True
- for
==,!=,<,>,<=,>=— comparison (see below)
Operations
x and y—Trueiffxandyare bothTrue(True and True) is True(False and True) is False(True and False) is False(False and False) is False(5 and 6) == 6- has short-circuiting behavior: If the left side is
False, the right side is not evaluated.
x or y—Trueiff at least one ofxandyisTrue(True or True) is True(False or True) is True(True or False) is True(False or False) is False(5 or 6) == 5- has short-circuiting behavior: If the left side is
True, the right side is not evaluated.
not x—TrueiffxisFalse(not True) is False(not False) is True
Note that
andandorare short-circuiting(5 or 1//0) == 5will run without errors.(0 and 1//0) == 0will run without errors.
Tuples (tuple)
- create by listing elements or comprehension (via generators):
tuple(2*x for x in (3, 1, 4)) == (6, 2, 8)tuple(2*x for x in (3, '1', 4)) == (6, '11', 8)
- if exactly one element, trailing comma required:
(1,)and not(1)
Conversion
tuple()takes in any sequence typetuple(('a', 'b', 'c')) == tuple("abc") == ('a', 'b', 'c')
Operations
+— concatenate tuples(1, 2) + (3, 4, 5) == (1, 2, 3, 4, 5)
*— replicate string("x", "y") * 3 == ("x", "y", 'x', 'y', "x", 'y')
x in t— element check4 in (3, 1, 4, 1, 5)
t.index(x)— element location (leftmost)(3, 1, 4, 1, 5).index(1) == 1
t[i]— indexing- get element at index
i t[0]is the first elementt[-1]is the last element- indexing starts at
0 - negative indices start at the back
(3, 1, 4, 1, 5)[2] == (3, 1, 4, 1, 5)[-3] == 4
- get element at index
t[i:j]— slicing- substring from index
iinclusive to indexjexclusive (3, 1, 4, 1, 5)[1:4] == (1, 4, 1)(3, 1, 4, 1, 5)[-2:] == (1, 5)(3, 1, 4, 1, 5)[2:2] == (3, 1, 4, 1, 5)[3:2] == ()
- substring from index
t[i:j:k]— slicing with step sizek(3, 1, 4, 1, 5)[2:4:2] == (4,)(3, 1, 4, 1, 5)[2:5:2] == (4, 5)(3, 1, 4, 1, 5)[1::2] == (1, 1)(3, 1, 4, 1, 5)[::-1] == (5, 1, 4, 1, 3)
len()— lengthlen((3, 1, 4, 1, 5)) == 5
==,!=,<,>,<=,>=— comparison (see below)
Lists (list)
- create by listing elements or comprehension (via generators):
[2*x for x in (3, 1, 4)] == [6, 2, 8][2*x for x in (3, '1', 4)] == [6, '11', 8]
Conversion
list()takes in any sequence typelist(('a', 'b', 'c')) == list("abc") == ['a', 'b', 'c']
Operations
+— concatenate tuples[1, 2] + [3, 4, 5] == [1, 2, 3, 4, 5]
*— replicate string["x", "y"] * 3 == ["x", "y", 'x', 'y', "x", 'y']
x in t— element check4 in [3, 1, 4, 1, 5]
t.index(x)— element location (leftmost)[3, 1, 4, 1, 5].index(1) == 1
t[i]— indexing- get element at index
i t[0]is the first elementt[-1]is the last element- indexing starts at
0 - negative indices start at the back
[3, 1, 4, 1, 5][2] == [3, 1, 4, 1, 5][-3] == 4
- get element at index
t[i:j]— slicing- substring from index
iinclusive to indexjexclusive [3, 1, 4, 1, 5][1:4] == [1, 4, 1][3, 1, 4, 1, 5][-2:] == [1, 5][3, 1, 4, 1, 5][2:2] == [3, 1, 4, 1, 5][3:2] == []
- substring from index
t[i:j:k]— slicing with step sizek[3, 1, 4, 1, 5][2:4:2] == [4,][3, 1, 4, 1, 5][2:5:2] == [4, 5][3, 1, 4, 1, 5][1::2] == [1, 1][3, 1, 4, 1, 5][::-1] == [5, 1, 4, 1, 3]
len()— lengthlen([3, 1, 4, 1, 5]) == 5
==,!=,<,>,<=,>=— comparison (see below)
Mutation
s.append(v)— insertvas the last elements.pop()— remove the last elements.pop(i)— remove the element at indexi- can be slow
s.clear()— clear the whole lists.insert(i, v)— insertvat indexi(the valuevis at indexiafter insertion)- can be slow
s.remove(v)— remove the leftmost occurrence of valuev- can be slow
s.extend(t)— append elements oftat the ends.sort()— sort the list in increasing/nondecreasing orders[i] = v— replace the value at indexibyvs[i:j] = seq— replace the given slice by the elements ofseqs[i:j:k] = seq— replace the given slice by the elements ofseq
Floats (float)
- try to minimize usage because of numerical errors!
0.1 + 0.1 == 0.20.1 + 0.2 != 0.3(1e20 + 1.0) - (1e20) == 0.0
Frozen Sets (frozenset)
- create via listing elements or comprehension (via generators):
frozenset(abs(x) for x in (-1, 0, 1, 0, 4, -3)) == frozenset((0, 1, 3, 4))
Conversion
frozenset()takes in any sequence typefrozenset(('a', 'b', 'c')) == frozenset("abaca")
Operations
|— union(frozenset((1, 2)) | frozenset((1, 3))) == frozenset((1, 2, 3))
&— intersection(frozenset((1, 2)) & frozenset((1, 3))) == frozenset((1,))
-— set difference(frozenset((1, 2)) - frozenset((1, 3))) == frozenset((2,))
x in t— element check4 in frozenset((3, 1, 4, 1, 5))
==,!=— equality<— proper subsetfrozenset((1, 3)) < frozenset((1, 2, 3))
<=— subsetfrozenset((1, 3)) <= frozenset((1, 2, 3))frozenset((1, 3)) <= frozenset((1, 3))
>— proper supersetfrozenset((1, 2, 3)) > frozenset((1, 3))
>=— supersetfrozenset((1, 2, 3)) >= frozenset((1, 3))frozenset((1, 3)) >= frozenset((1, 3))
len()— lengthlen(frozenset((3, 6, 3))) == 2
Sets (set)
- create via listing elements or comprehension:
{abs(x) for x in (-1, 0, 1, 0, 4, -3)} == {0, 1, 3, 4}
- empty set:
set()(not{}!)
Conversion
set()takes in any sequence typeset(('a', 'b', 'c')) == set("abaca") == {'a', 'b', 'c'}
Operations
|— union({1, 2} | {1, 3}) == {1, 2, 3}
&— intersection({1, 2} & {1, 3}) == {1}
-— set difference({1, 2} - {1, 3}) == {2}
x in t— element check4 in {3, 1, 4, 1, 5}
==,!=— equality<— proper subset{1, 3} < {1, 2, 3}
<=— subset{1, 3} <= {1, 2, 3}{1, 3} <= {1, 3}
>— proper superset{1, 2, 3} > {1, 3}
>=— superset{1, 2, 3} >= {1, 3}{1, 3} >= {1, 3}
len()— lengthlen({3, 6, 3}) == 2
Mutation
s.add(v)— addvas an element of the sets.remove(v)— removevas the last elements.pop(i)— remove the element at indexi- can be slow
s.clear()— clear the whole set
Dictionaries (dict)
- maps keys to values
- fast lookup from keys to values
- keys are unique
- keys must be immutable
- create via listing key-value pairs or comprehension:
{x: x**2 for x in (3, 0, -3)} == {0: 0, -3: 9, 3: 9}
- empty dict:
{}
Conversion
dict()takes in any sequence of pairsdict((('a', 1), ('b', 2))) == {'a': 1, 'b': 2}
Operations
d[k]— get value corresponding to keyk{1: 2, 3: 4}[3] == 4
k in d— key check1 in {1: 2, 3: 4}2 not in {1: 2, 3: 4}
==,!=— equalitylen()— length (number of key-value pairs)len({1: 4, 2: 5, 1: 6}) == 2
d.keys()— go through keys{k for k in {1: 2, 3: 4}.keys()} == {1, 3}
d.values()— go through values{v for v in {1: 2, 3: 4}.values()} == {2, 4}
d.items()— go through key-value pairs{kv for kv in {1: 2, 3: 4}.items()} == {(1, 2), (3, 4)}
Mutation
d[k] = v— set value corresponding to keyktovdel d[k]— remove keykd.pop(k)— remove keykand return corresponding valued.clear()— clear the whole dictd.update(d2)— add key-value pairs of the given dict
Variables
- name must not start with digit
- binding/assignment
x = ymeans "make the namexpoint to the valuey"- is not mathematical equality! (Use
==)val = 5 num = val
- destructuring bind
(x, y) = (1, 2) ((a, b), (c, d)) = ((1, 2), (3, 4))
Syntax
Indentation
HEADER:
STATEMENT1
STATEMENT2
STATEMENT3
- block: collection of statements at same level
- line before them have lower indentation level and always ends with
:
- line before them have lower indentation level and always ends with
If-elif-else
if condition1:
... # do if condition1 true
elif condition2:
... # do if condition1 false and condition2 true
elif condition3:
... # do if condition1, condition2 both false and condition3 true
else:
... # do if all three conditions false
- Can have any number of
elif(including zero) elseis optional
Function definition
def has_real_root(a, b, c):
d = b**2 - 4*a*c
return d >= 0
- exits as soon as it reaches a
return; the first one it encounters - variables inside are "local"—can't be accessed outside
- returns
Noneif exited without reaching areturnstatement
Pass
pass
- does nothing. Useful when the syntax requires a block, but you want it empty
Comments
# Comments are ignored
LEGENDRES_CONSTANT = 1 # Legendre's constant up to 420 correct decimal places
Chaining
- chaining is allowed
1 < 3 > 2 == 2 <= 2
Splat (aka. unpacking)
- can splat to pass args
x = (1, 2, 3)
y = 4
z = (5, 6)
print(*x, y, *z)
- can splat to make tuples, lists, sets
(*x, y, *z) == (1, 2, 3, 4, 5, 6)[*x, y, *z] == [1, 2, 3, 4, 5, 6]{*x, y, *z, *x} == {1, 2, 3, 4, 5, 6}
Dictionary Splat
w1 = {1: 2, 3: 4}
w2 = {5: 6}
print({4: 5, **w1, **w2})
Variadic functions
def print_lol(*args):
print(*args, 'haha')
print_lol("kumusta")
def f(a, b, c, *rest):
# function with at least three arguments
...
- function with any number of arguments
Comprehension
def get_evens(seq):
return tuple(x for x in seq if x % 2 == 0)
def cartesian_product(s, t):
return frozenset((x, y) for x in s for y in t)
def even_sum_pairs(seq1, seq2):
# all pairs whose sum is even
return [(v1, v2)
for v1 in seq1
for v2 in seq2
if (v1 + v2) % 2 == 0
]
- similar to set-builder notation in math, e.g., \(\{(x, y) \mid x \in S, y \in T \}\)
Assertion
assert is_even(6)
assert not is_even(5)
- raises error if condition is false
- used to as sanity check throughout code
- do not use this for input validation
- intended to always pass; a failing assertion is a bug
Ternary Operator
def f(x):
a = ('positive' if x > 0 else 'nonpositive')
b = ('even' if x % 2 == 0 else 'odd')
return f"{a} {b} integer"
print(f(5)) # positive odd integer
print(f(-4)) # nonpositive even integer
- a conditional expression
f-strings
msg = f"The age of {name} is {age}."
- convenient way to build strings`
Raising an Exception
raise ValueError(f"The number {n} is invalid")
- raise an exception
Handling/Catching an Exception
try:
some_operation_that_might_fail()
except TypeError:
print("A TypeError was raised!")
except ValueError:
print("A ValueError was raised!")
except Exception:
print("It raised an exception that's not TypeError or ValueError!")
else:
print("No exception occurred, yay!")
except:to catch an exception of a given typeexcept Exception:as a catch-all. put it lastelse:for the case where no exception occurred
For Loops
for digit in (3, 1, 4, 1, 5):
print(digit)
sm = 0
for d in [3, 1, 4]:
sm += d
print(d)
print(sm)
- perform block of code for each element of the given sequence
While Loops
x = 10**9
while x > 0:
print(x)
x //= 2
- repeats block of code while the condition is true
Break
def collatz_seq(n):
while True:
yield n
if n == 1:
break
n = collatz(n)
- exits a
fororwhileloop - try to use sparingly
Generators
def all_evens(seq):
for v in seq:
if v % 2 == 0:
yield v
for v in all_evens([3, 1, 4, 1, 5, 9, 2]):
print(v)
# generator expression
s = (v**2 for v in range(5))
print(list(s)) # [0, 1, 4, 9, 16]
print(list(s)) # []
- one-time-use sequence
next(g)to get the next element- for loops and comprehensions can naturally deal with them
iter(seq)to make a generator from any sequence type- lazily evaluates—only executes when next element is needed, and then pauses once it
yields or exits
def nonempty_substrings(s):
for i in range(len(s)):
yield from substrings_starting_from(s, i)
yield fromtoyieldevery element of another sequence/generator
Starred assignment
(a, b, *c, d, e) = 'bananaman'
print(a) # b
print(b) # a
print(c) # ['n', 'a', 'n', 'a', 'm']
print(d) # a
print(e) # n
- can only have one star (
*) on the left
Import
from math import cos, pi
print("The cosine of", pi, "is", cos(pi))
import math
print("The cosine of", math.pi, "is", math.cos(math.pi))
- loads variables and functions from modules
Miscellaneous
Special Values
None— generic value representing "don't care" or nothingness- returned by functions that exited without reaching a
returnstatement
- returned by functions that exited without reaching a
Special Functions
chr(code)— the character with ASCII codecodechr(97) == 'a'
ord(ch)— the ASCII code of characterchord('a') == 97
repr(x)— python representation of valuexprint(...)— display as outputinput()— take a line of input (probably won't be used in OJ)type(x)— the "type" ofxrange(n)— goes from0ton-1tuple(i**2 for i in range(4)) == (0, 1, 4, 9)
range(i, j)— goes fromitoj-1tuple(range(1, 5)) == (1, 2, 3, 4)
range(i, j, k)— goes fromitoj-1with step sizektuple(range(1, 5, 2)) == (1, 3)tuple(range(5, 1, -2)) == (5, 3)range(5, 0, -2)[::-1] == range(1, 7, 2)
isinstance(some_value, some_type)— check that a value is of a given typeisinstance(5, int)not isinstance(5.0, int)
sorted(seq)— return a sorted version ofseqsorted(v**2 for v in range(-2, 3)) == [0, 1, 1, 4, 4]
sum(seq)— the sum of the elements ofseqsum(v**2 for v in range(-2, 3)) == 10
min(seq)— the minimum of the elements ofseqmin(v**2 for v in range(-2, 3)) == 0
max(seq)— the maximum of the elements ofseqmax(v**2 for v in range(-2, 3)) == 4
min(x, y),min(x, y, z), etc. — the minimum of the argumentsmin(3, 1, 4) == 1
max(x, y),max(x, y, z), etc. — the maximum of the argumentsmax(3, 1, 4) == 4
abs(num)— the absolute value of the numbernumabs(5) == abs(-5) == 5abs(0) == 0
any(seq)—Trueiff at least one element ofseqis trueany((0, 2, 1)) is Trueany((0, False, "")) is Falseany(v > 2 for v in range(5)) is True
all(seq)—Falseiff at least one element ofseqis falseall((2, 0, 1)) is Falseall((-1, 'abc', [3])) is Trueall(v > 2 for v in range(5)) is False
enumerate(seq)— same sequence but with indices in front[*enumerate('abc')] == [(0, 'a'), (1, 'b'), (2, 'c')][*enumerate('abc', 3)] == [(3, 'a'), (4, 'b'), (5, 'c')]
zip(seq1, seq2)— generates pairs of corresponding elements[*zip((1, 2, 3), 'abc')] == [(1, 'a'), (2, 'b'), (3, 'c')]- can receive any number of sequences
reversed(seq)— generates the elements of sequenceseqin reverse[*reversed((1, 2, 3))] == [3, 2, 1]- does not support pure generators
iter(seq)— make a generator from the sequenceseqnext(g)— get the next element of generatorg- raises
StopIterationwhen there are no more
- raises
Comparison: Equality
==— equals!=— does not equal
works for most types
Comparison: Ordering
<— less than>— greater than<=— less than or equal>=— greater than or equal
works for: numeric types, tuples, lists, bools
for frozensets, interpreted as subset and superset operations
Exceptions
IndexError— index out of bounds"HAL"[9000]
TypeError— operand doesn't have correct type123 + "456"
NameError— name not foundprint(a_nonexistent_variable)
SyntaxError— invalid Python programx = 1 /// 2
AttributeError— attribute access fails"half life 3".develop()
ValueError— operand type okay, but value is illegalint("six")
AssertionError— an assertion failsassert 2 + 2 == 5
IOError— I/O system reports failure (e.g., file not found)with open("a_nonexistent_file.txt") as file:
KeyError— when something is not found in sets or dictionaries{'1': '2'}['2']
StopIteration— when taking the next element of a fully-consumed generatornext(iter([]))
Exception— catch-all
Augmented Assignment
x += y— increasexbyyx -= y— decreasexbyyx *= y— multiplyxbyy
other binary operators have similar "assignment" versions:
+=-=*=%=//=/=**=|=&=
Modules
itertools:
count(),count(start),count(start, step)— counts up everystep(default1), starting fromstart(default0)[*islice(count(15, 2), 3)] == [15, 17, 19]
Strategy and Tactics
- DRY — Don't Repeat Yourself
- copy-pasting is often bad
- make functions (abstraction)
- KISS — Keep It Simple, S*****
- functions should have one simple well-defined job
- if function is getting too long, split to multiple functions
- convert tabs to 4 spaces
- Preferences → Settings
- make sure
"translate_tabs_to_spaces": trueis on the right - separate different options with commas
- add current working folder in Sublime sidebar
- Sublime Text → Add Folder to Project → (select your folder)
- bottom-up programming
- top-down programming, a.k.a., "wishful thinking", to know what tools you'll probably need
- use
asserts for sanity check - unit testing
- add
asserts for the given examples, as well as more examples you can come up with - dedicate a section of code for the unit tests
- think of typical and atypical cases, edge cases, extreme cases
- tester wants to break the program
- add
- test-driven development—try to add tests to each function even before implementing them
- separate I/O part from main logic part
- EAFP — it is Easier to Ask for Forgiveness than Permission
- don't check conditions before doing something; just do it, and then handle the case when it doesn't work
- avoid mutable global variables if possible