Jed Rembold
October 24, 2025
from pgl import GWindow, GImage
def threshold(e):
thresh_value = 30
height = len(pixels)
width = len(pixels[0])
new_array = [[0 for i in range(width)] for i in range(height)]
for r in range(height):
for c in range(width):
if GImage.get_red(pixels[r][c]) > thresh_value:
new_array[r][c] = GImage.create_rgb_pixel(0, 255, 0)
else:
new_array[r][c] = GImage.create_rgb_pixel(0, 0, 0)
new_image = GImage(new_array)
gw.add(new_image)
gw = GWindow(800, 525)
image = GImage("Moon.png")
gw.add(image)
pixels = image.get_pixel_array()
gw.add_event_listener("click", threshold)
The Python package used to implement
pgl.py also supports a mechanism to choose
files interactively, made available through the
filechooser.py library module.
filechooser.py exports two
functions:
choose_input_file for selecting a
filechoose_output_file for selecting a
folder and filename to save a file toBoth open up a file dialog that lets you select/choose a file
Using it thus looks something like:
filename = choose_input_file()
with open(|||filename|||) as |||f|||:
|||Code to read file|||The general approach for reading a text file is to first open the file and associate that file with a variable, commonly called its file handle
We will also use the with keyword to ensure that Python
cleans up after itself (closes the file) when we are done with it (Many
of us could use a with irl)
with open(|||filename|||) as |||file_handle|||:
|||Code to read the file using the file_handle|||Python gives you several ways to actually read in the data
read reads the entire file in as a
stringreadline or
readlines reads a single line or lines from
the fileThe read method reads the entire file
into a string, with includes newline characters
(\n) to mark the end of lines
Simple, but can be cumbersome to work with the newline characters, and, for large files, it can take a large amount of memory
As an example, the file:
One fish
two fish
red fish
blue fish
would get read as
"One fish\ntwo fish\nred fish\nblue fish"
Of the ways to read the file in a string at a time, using the file handler as an iterator and looping is probably best and certainly most flexible
Leads to code that looks like:
with open(|||filename|||) as |||f|||:
for line in |||f|||:
|||Do something with the line|||Note that most strategies preserve the newline character, which you very likely do not want, so be ready to strip them out before doing more processing
| Method | Description |
|---|---|
|||string|||.split() |
Splits a string into a list of its components using whitespace as a separator |
|||string|||.split(|||sep|||) |
Splits a string into a list using the specified separator
sep |
|||string|||.splitlines() |
Splits a string into of list of strings at the newline character |
|||string|||.join(|||a_list|||) |
Joins the elements of the a_list into a
string, using string as the separator |
So long as your files are not gigantic, using
read and then the
splitlines method can be a good
option
This does remove the newline characters, since it splits the string at them
with open(|||filename|||) as |||f|||:
lines = |||f|||.read().splitlines()
|||Then you can do whatever you want with the list of lines|||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 fileTo 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])
GImagefrom 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.