Speed Review: Midterm Edition!
Data Types/Functions
Printing with end: end parameter means the line ends with the value passed (default is ‘\n’):
print(“blah”, end=” “) ends line with space and next print statement starts after space
Error Types:
● Syntax: code looks grammatically bad
● Runtime: code looks grammatically ok, but runs bad
● Logical: code looks grammatically ok, runs ok, but doesn’t work like expected
Negative integer division goes down to the more negative number: -7//3 == 7//-3 == -3
Mod (for when negative numbers are involved): a%b == (a-(a//b)*b)
Exponents: read right to left (←): 2**2**3 == 256 (2**8)
Floating-point approx. is not completely accurate/off by a bit (use math.isclose() instead): 0.1
+ 0.1 + 0.1 != 0.3
Short circuit:
● and: False and ____
● or: True or ___
Functions always return None if no return statement is specified
Assert crashes if it’s false
Loops
For loops: when you know the exact number of times to loop (i.e. wash plates 5 times)
While loops: when you don’t know the exact number of times to loop - usually have a condition
instead (i.e. wash plates until done)
range(start, end, step)
● Start: included
● End: excluded
Sum digits:
def sumDigits(n):
total = 0
while n > 0:
total += n % 10
n //= 10
return total
Nth template:
def nthBlah(n):
guess = 0
found = 0
while found <= n:
guess += 1
if isBlah(guess):
found += 1
return guess
Best template (largestNumber example: takes a string and finds the largest number)
Key idea: having a best and current variable and updating them appropriately
def largestNumber(s):
best = 0
current = 0
for c in s:
if c.isdigit():
current = current * 10 + int(c)
else:
if current > best:
best = current
current = 0
if current > best: # for when the entire string is a number
best = current
return best
Strings
Strings are immutable!!! (no .pop(), .remove(), etc.) instead: s = s[:index] + s[index + 1:]
String index example (including negative equivalents):
“ h e l l o w o r l d “
0 1 2 3 4 5 6 7 8 9 10
-11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1
Escape sequences that are actually length 1 (Note \ by itself/not escape sequence is length 1):
● \”
● \\
● \n
● \t
Multiplying strings is ok: “wow” * 3 == “wowwowwow”
Slicing: s[start:end:step]
● Start: inclusive
● End: exclusive
● s[index:] index to end
● s[:index] up to index (exclusive)
● s[::-1] reverse string
● Watch out for bad direction: s[0:2:-1] == “”
Some particularly useful functions:
● s.replace(old, new[, max]) replaces instances of old in s with new (optional
max parameter)
● s.count(substring) returns number of times substring appeared in s
● s.startswith(substring) checks if s started with substring
● s.endswith(substring) similar idea to above/startswith
● s.find(substring) returns starting index of substring in s
○ Does not crash if substring doesn’t exist, returns -1 instead
● s.index(substring) exact same idea to above/find but:
○ Crashes if substring doesn’t exist
1D Lists
Appending vs. extending:
Append creates another cell and puts whatever parameter was passed inside the cell
Extend concatenates the parameter (must be a list) to the list
L = [1, 2, 3]
L.append([4]) == [1, 2, 3, [4]]
L.extend([4]) == [1, 2, 3, 4]
(Note extend() behaves somewhat similarly to the following, but they are not the same!):
L += [4] == [1, 2, 3, 4]
L = L + [4] == [1, 2, 3, 4]
Destructive vs. Non-destructive Methods (Particularly confusing ones highlighted):
Non-Destructive Destructive
● L = L + lst ● L += lst
● L = L[:index] ● L.extend(lst)
● sorted(L) ● L.append(item)
● reversed(L) ● L.insert(index, item)
● L.index(index) ● L[index] = value
● L.count(item) ● del L[index]
● L.remove(item)
● L.pop(index)
● del(L[:index])
● L.sort()
● L.reverse()
Aliasing vs. copying without aliasing
Copying without aliasing Aliasing
● a = copy.copy(b) ● a = b
● a = copy.deepcopy(b)
● a = b + []
● a = b[:]
● a = list(b)
.pop() removes the last value of the list if no index is specified and returns the popped value
Some useful builtins:
● L.count(item) returns the number of occurrences of item in L
● L.sort() or sorted(L) sort a list in order
● L.reverse() or reversed(L) reverse a list (most useful for looping through a list
backwards!: for item in reversed(L))
Tuples are immutable!
2D Lists
Starting a 2D list
● Static allocation (w/ fixed values): L = [[1, 2], [3, 4]]
● Dynamic allocation (variable-length):
○ DO NOT (will alias rows): L = [[0] * cols] * rows
○ DO: for row in range(rows): L += [[0] * cols]
○ DO: L = [[0] * cols for row in range(rows)]
copy.copy(L) now does a shallow copy (the rows will be aliased still)
copy.deepcopy(L) instead (Note: pretty much any copy is a shallow copy except for
copy.deepcopy)
See 1D list notes for row-wise aliasing
OOP
Main idea: If you want to make objects that contain specific qualities and abilities, use classes!
● Attributes: The qualities of your objects, define them in __init__ (Ex: name, physics
attributes, etc.)
● Methods: The abilities of your objects, define them as methods within your class (Ex:
move(), eat(), etc.)
All class methods pass self as an attribute!
How to differentiate methods vs attributes when reading code: methods end with () but attributes
do not!
● dog.isRunning -> attribute (no parentheses)
● dog.run() -> method (parentheses!)
Graphics
Drawing methods:
● Shapes (Note: dimensions can be inputted as a list)
○ canvas.create_rectangle(topX, topY, bottomX, bottomY)
○ canvas.create_oval(topX, topY, bottomX, bottomY)
■ When creating a circle, do it relative to the center: cx - r, cy - r,
cx + r, cy + r
○ canvas.create_polygon(x1, y1, x2, y2, x3, y3, etc..)
○ canvas.create_line(x1, y1, x2, y2)
■ Does not have outline parameter
○ Extra parameters:
■ fill [color string]: specify color to fill
■ width [float or int]: specify thickness of outline
■ outline [color string]: specify color for outline
● Text:
○ canvas.create_text(x, y, text = [string])
■ fill [color string]: text color
■ font [string]: format: Font type_Font size_Extra features
■ anchor [string]: default = “CENTER” (see below for others):
Anchors relative to canvas:
SE S SW
E CENTER W
NE N NW
Drawing circles given center x (cx), center y (cy), angle (in radians, so use math.pi), and
radius (r):
● x = cx + r * math.cos(angle)
● y = cy - r * math.sin(angle)
YOU CAN DO IT!!!! :)