Jed Rembold
October 27, 2025
To the right are the contents of a text file named
PBride.txt. Which code snippet below would
print off the word “father”?
My name is Inigo Montoya.
You killed my father.
Prepare to die.
with open('PBride.txt') as f:
for line in f:
w = line.split()
if w[0] == "You":
print(w[-1])
c = read('PBride.txt')
print(c.find("father"))
with open('PBride.txt') as f:
c = f.read().splitlines()
print(c[1][4])
with open('PBride.txt') as f:
c = f.read()
i = c.find("f")
print(c[i:i+6])
You can write text files using almost the same syntax as reading:
with open(|||filename|||, |||mode|||) as |||file_handle|||:
|||Code to write the file using file_handle|||Note the |||mode||| parameter to
open here! Mode is a string which is
either
"w" to write a new file
(or overwrite an existing file)"a" to append new
contents to the end of an existing fileThe file handler supports the methods:
.write(|||string|||) to write a string
to the file.writelines(|||iterable of strings|||)
to write each iterable element to the fileGImagefrom pgl import GWindow, GImage, GOval
SCALE_FACTOR = 3
MARKER_SIZE = 10
with open('User1_Original.txt') as fh:
name = fh.readline().strip()
width = int(fh.readline().strip())
height = int(fh.readline().strip())
fp = fh.read().splitlines()
# Initially clean out points for new run
with open('points.txt', 'w') as fh:
pass # Not doing anything, because just opening it clears things
print(name)
print(width)
print(height)
print(fp) #list of strings
# Make our scaled window
gw = GWindow(SCALE_FACTOR*width, SCALE_FACTOR*height)
# Create our array and populate it
pixel_array = [[0 for i in range(width)] for j in range(height)]
for r in range(height):
for c in range(width):
if fp[r][c] == 'M':
pixel_array[r][c] = GImage.create_rgb_pixel(0,0,0)
else:
pixel_array[r][c] = GImage.create_rgb_pixel(255,255,255)
# Convert our pixel array to a GImage, scale it, and add it
fp_image = GImage(pixel_array)
fp_image.scale(SCALE_FACTOR)
gw.add(fp_image)
# Handling interactivity
def click_action(e):
"""Marks the clicked loc with a red dot and writes to file"""
mx, my = e.get_x(), e.get_y()
marker = GOval(mx - MARKER_SIZE/2, my - MARKER_SIZE/2,
MARKER_SIZE, MARKER_SIZE )
marker.set_filled(True)
marker.set_color("red")
gw.add(marker)
with open('points.txt', 'a') as fh:
fh.write(f"{mx},{my}\n")
gw.add_event_listener("mousedown", click_action)
GImage type objectGrayscaleImage.py that you can import into
your main programGButtonGButton gets a label and a callback
function name that determines what function is called when that button
is clickedadd_button function which will take care of
adding a new button to the correct part of the screen.
GImage currently
displayed on the window in a variable called
gw.current_imagegw so that you will have access to it in any
callback function you writeset_image on the output of your manipulation
function, which will take care of updating the value of
gw.current_image and displaying the new
image in the windowImageShop.py as needed.
| 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|||