Jed Rembold
October 29, 2025
Suppose you had the file contents to the left and wanted to turn it into the contents on the right. Which code snippet below would accomplish this?
12345
1234554321
with open('OG.txt') as fh:
data = fh.read()
with open('OG.txt', 'w') as fh:
fh.write(data[::-1])
with open('OG.txt', 'rw') as fh:
data = fh.read()
fh.write(data[::-1])
with open('OG.txt') as fh:
data = fh.read()
with open('OG.txt', 'a') as fh:
fh.write(data[::-1])
with open('OG.txt') as fh:
data = fh.read()
with open('OG.txt', 'a') as fh:
fh.write(data[-2::-1])
| name | title | salary |
|---|---|---|
"Ebenezer Scrooge" |
"founder" |
1000 |
"Bob Cratchit" |
"clerk" |
15 |
employee = ("Bob Cratchit", "clerk", 15)You can select or slice elements from a tuple just like you can with lists
If using tuples, you can make programs more readable by using a destructuring assignment, which breaks a tuple into named components:
name, title, salary = employeeWhile modern versions of Python have such thing as a named tuple, we will not look at them here.
One of the most simple examples of tuple usage would be storing location information in 2d space
By storing both \(x\) and \(y\) coordinates in a tuple, it makes that information easier to store and pass around your program
When you need to use the points, best to destructure:
x,y = ptDELTA ahead

from pgl import GWindow, GLine, GRect
PEG_SEP = 3
PEG_ACROSS = 300
PEG_DOWN = 150
DELTA = 332
GWIDTH = PEG_ACROSS * PEG_SEP
GHEIGHT = PEG_DOWN * PEG_SEP
def place_pegs():
""" Returns a list of points, where the points are tuples. """
list_pts = []
for i in range(PEG_ACROSS):
list_pts.append((i * PEG_SEP, 0))
for i in range(PEG_DOWN):
list_pts.append((GWIDTH, i * PEG_SEP))
for i in range(PEG_ACROSS):
list_pts.append((GWIDTH - i * PEG_SEP, GHEIGHT))
for i in range(PEG_DOWN):
list_pts.append((0, GHEIGHT - i * PEG_SEP))
return list_pts
def draw_pattern(list_pts, color='black'):
""" Creates a window and draws in the necessary yarn. """
gw = GWindow(GWIDTH, GHEIGHT)
current_i = 0
finished = False
while not finished:
next_i = (current_i + DELTA) % len(list_pts)
x1, y1 = list_pts[current_i]
x2, y2 = list_pts[next_i]
line = GLine(x1, y1, x2, y2)
line.set_line_width(2)
line.set_color(color)
gw.add(line)
current_i = next_i
if current_i == 0:
finished = True
if __name__ == '__main__':
pegs = place_pegs()
draw_pattern(pegs, 'green')
return x, y is the same as
return (x,y)enumeratezipWe have multiple ways to iterate through a string or list:
By element:
for ch in string:
|||body of loop using ch|||By index:
for i in range(len(string)):
|||body of loop using i|||Using enumerate lets us get both!
for i, ch in enumerate(string):
|||body of loop using both ch and i|||Sometimes you have multiple lists that you want to loop over in a “synced” fashion
The zip function iterates through
tuples of pairs of elements
For example
zip([1,2,3], ["one", "two", "three"])
would yield (1, "one"), then
(2, "two"), and then
(3, "three")
Can unpack or destructure as part of a
for loop:
for x,y in zip([1,2,3],[4,5,6]):
|||body of loop using paired x and y|||GRect class.
GRect classClass definitions in Python start with a header line consisting
of the keyword class and then the class
name
The body of the class will later contain definitions, but initially can just leave blank
pass keywordclass Employee:
"""This class is currently empty!"""Once the class is defined, you can create an object of this class type by calling the class as if it were a function:
clerk = Employee()You can select an attribute from an object by writing out the object name, followed by a dot and then the attribute name.
As an example
clerk.name
would select the name attribute for the
clerk object
Attributes are assignable, so
clerk.salary *= 2
would double the clerk’s current salary
You can create a new attribute in Python by simply assigning a name and a value, just like you’d define a new variable
We could, for instance, create a
clerk in the following fashion:
def create_clerk():
clerk = Employee()
clerk.name = "Bob Cratchit"
clerk.title = "clerk"
clerk.salary = 15
return clerkNote that none of these assigned attributes affect the
Employee class in any way
We could accomplish this more generally by passing arguments to our function:
def create_employee(name, title, salary):
emp = Employee()
emp.name = name
emp.title = title
emp.salary = salary
return empWe could then use that as:
clerk = create_employee('Bob Cratchit', 'clerk', 15)
boss = create_employee(
'Ebeneezer Scrooge', 'founder', 1000
)Employee
class called a constructor, which is responsible for
initializing attributes to a newly created object
__init__selfselfselfs in the class with that object’s name
self is
doingself is always the
first parameter to the __init__ constructor
class Employee:
def __init__(self, name, title, salary):
self.name = name
self.title = title
self.salary = salary
clerk = Employee('Bob Cratchit', 'clerk', 15)
self when creating the object, Python
supplies this reference automatically