Published using Google Docs
Lab 8 Compsci 101, Fall 2025
Updated automatically every 5 minutes

Lab 8 Compsci 101, Fall 2025

Lab Reflect/Questions and Starter Code

Part 1: Dictionary to Dictionary (15 minutes)

Part 2. Images (25 min)

Part 3: Reflection on Debugging (5 minutes)

Part 4: Review A Little on Debugging (5 minutes)

Debugging Mindset

Remember the steps for debugging

Remember the 5 W’s

Order of Operations and Ways to Debug

Part 5: Debugging Exercises (20 minutes)

Lab Reflect/Questions and Starter Code

As you're completing this lab, complete this form.

You can find the .zip file containing all code linked here.

Part 1: Dictionary to Dictionary (15 minutes)

Consider the following dictionary named data that maps a string that is a netid to a list of strings where each string is the course a student with that netid is currently taking.

Now consider we want to find out for each course, the netid’s of who is in that course. The dictionary above is not setup well for that. Instead, we should  take that dictionary data as input and create a dictionary that maps a course to a list of netid’s of students that are in that course. If we use the dictionary above as input, we would get this dictionary:

In the file ReverseDictionary.py, which you downloaded as part of this lab,  complete the function reverse that takes as input a dictionary in the format data is in above (netid to list of courses) and returns a dictionary in the format of revdata below (course to list of netid’s in the course).

It is very important to use meaningful variable names since you have two dictionaries with different keys and different values.

Answer the following questions:

  1. What is a good variable name for the key in the dictionary d1 (which is the same type of dictionary as data)?
  2. What is a good variable name for one of the strings in the list for d1’s values?
  3. What is the code for function reverse?

Part 2. Images (25 min)

In this lab we will explore Images.  Each image is made up of pixels. A pixel is a tuple of three RGB values.

Images are a powerful way of conveying information and computers give us a powerful way of modifying images. This lab involves manipulating pixmaps by transforming each color in the original pixmap using the same algorithm (such as darkening, inverting, posterizing, converting it to grey scale). Your programs will then perform several operations on these images to achieve a larger effect.

Images are stored by computers in a variety of formats, such as GIF, JPG/JPEG, TIFF, and PNG. These formats differ in how faithfully they represent the original picture, how well they can be compressed to reduce the space each image takes up, or how well they can be copied from one type of computer to another. However, no matter what format the image is stored in, it can always be represented as a mapping of (x, y) pixel position to a color (the range of colors may be restricted to values of grey or just black and white). Thus, for the remainder of this project, we will refer to all formats of digital images as images.

This week's lab uses the Python Imaging Library (PIL) with info here which provides a simple interface for processing images. We will create basic color filters (RGB color model) that can be applied to images then combine them to create larger effects.

If you haven't yet, you will need to install PIL. In Pycharm, go to the terminal window.

At the prompt, type:       pip install Pillow 

If that doesn't work, you can also try to type:     Python3 -m pip install Pillow;

In lecture we saw a program grayscale.py to take an image and create a new image that is the grayscale version of the previous image. We have included grayscale.py. Try running that program. An image should pop up and a copy of that image in grayscale should also pop up.

Let's look at the code from grayscale.py. We turned the image gray two different ways. One way was using the function grayByPixel which calls the function getGray:

def getGray(r,g,b):

   gray = int(0.21*r + 0.71*g + 0.07*b)

   return (gray,gray,gray)

def grayByPixel(img, debug=False):

   width = img.width

   height = img.height

   new_img = img.copy()

   if debug:

       print("creating %d x %d image" % (width,height))

   for x in range(width):

       for y in range(height):

           (r,g,b) = img.getpixel((x,y))

           grays = getGray(r,g,b)

           new_img.putpixel((x,y),grays)  

   return new_img

In this function grayByPixel makes a copy of the image, goes through every Pixel in an (x,y) position, creates a gray color of the pixel by calling the function getGray,  and puts the new pixel in the copy of the image.

We also saw another way to convert an image to grayscale that called this function grayByData, which also calls getGray above:

def grayByData(img, debug=False):

   pixels = [getGray(r,g,b) for (r,g,b) in img.getdata()]

   new_img = Image.new("RGB", img.size)

   new_img.putdata(pixels)

   if debug:

       print("created %d x %d gray image" % (img.width,img.height))

   return new_img

In the function grayByData, the function uses a list comprehension and the image function im.getdata() to process all the pixels in a stream of data, to create a list of all the pixels turned gray and then uses the image function putdata to put all the new pixels in the list pixels into the image at once.

You will do three things to images.

  1. In the file ReddenImage.py, you will modify the function getRedder to make an image redder by increasing the red and decreasing the blue and green. This code will be similar to making an image gray. In particular modify the function getRedder(r, g, b),  the  r, g, and b from a pixel,  and make the red (r) 100 more, the green (g) 50 less and the blue (b) 50 less. Be sure not to go outside the bounds of 0 to 255, the values that r, g, and b can be. Run your program to see if the image is redder. See the example below where the image on the right is redder.

  1. Next in the file FlipImage.py, you will flip an image horizontally [flip upside down over a horizontal line]. Look at the two functions above grayByData and grayByPixel and decide which one would work best as a starting point for the function flipHorizontally. You should also think about whether or not a helper function would be useful. Write the function flipHorizontally and test it out. See the example below of the BlueDevil image on the left, and the image flipped on the right.

  1. Next in the file PosterizeImage.py, write the function posterize(img) to "posterize" the image, that is to make it look like a poster by reducing its total number of colors. How do you do that? To do this, you should restrict the values of each of the three RGB channels of the pixel so that it takes on four distinct values based on a level-range. Specifically, if the value of each R,G,B is between 0 and 63 inclusive, it should be set to 50; if the value is between 64 and 127 inclusive, it should be set to 100; if the value is between 128 and 191 inclusive, it should be set to 150; and if the value is between 192 and 255 inclusive, it should be set to 200. In this way, the 256 possible values each channel can have is restricted to just 4. See the example of the posterized image on the right below.

Answer the following questions based on this code:

  1. Include your code of getRedder() you wrote to redden an image.
  2. Include your code of flipHorizontally() and any helper functions you wrote, if any.
  3. Include your code of posterize() and any helper functions you wrote, if any.

Part 3: Reflection on Debugging (5 minutes)

In small groups, think back and discuss the last time you had a bug in your code and answer the following questions:

  1. What was the context (assignment, APT, etc.) and what was the problem?
  2. What did you do?
  3. If you got help, what did that person do/have you do?
  4. Did you try multiple things? What were they?

Compare your experience with a classmate by discussing your responses to the previous questions. If you are completing this lab on your own, just record your responses in the lab form.

  1. Give a brief overview of your partner’s problem and solution to their problem.

Part 4: Review A Little on Debugging (5 minutes)

Debugging Mindset

Debugging is a mindset! Many say that “debugging comes with practice.” This is a new skill that you are learning; if it seems challenging now, it is important to not be too hard on yourself. As when learning anything new, things may be overwhelming at first because you don’t know what to pay attention to. There are many ways to tackle debugging, and as you gain experience, your sense of which “way” to try first gets better.

Remember the steps for debugging

  1. Write down exactly what is happening
  1. input, output, what should be output
  2. ____ happened, but ____ should happen
  1. Brainstorm possible reasons this is happening
  1. Write down ideas
  1. Go through list        
  2. Found it?
  1. Yes, fix it using the 7-steps
  2. No, go back to step 2

Remember the 5 W’s

You may remember that the 5 W’s are:

  1. Who was involved?
  2. What happened?
  3. Where did it take place?
  4. When did it take place?
  5. Why/How did it happen?

In the context of debugging, these questions can be translated to:

  1. Which variables are involved?
  2. What kind of error/bug is it?
  3. Where in the code did this happen?
  4. Does it happen every time? For certain cases?
  5. Given the answers to the above, how did the error/bug happen?

Answering these questions can help you brainstorm so you can find and squash the bugs in your code.

Order of Operations and Ways to Debug

When you fail a test or get an error, these steps generally will help you identify the problem:

  1. Write code that reproduces the problem reliably. (step 1 of debugging)
  2. Debug (steps 2-4 of debugging)

Notice debug is not the only thing on this list! Writing code that reproduces the bug does two things:

  1. Helps you understand the bug better
  2. Make it faster to check if you've fixed it.

Once you can reproduce the problem, here are a few methods to debug:

Part 5: Debugging Exercises (20 minutes)

With this background, we can practice with a few examples. You’ll need to import the lab code from the link above.

In the zip file, you will find 3 examples: ReadQuizScore, RepeatInOrder, and VenmoTracker. These all link to the problem specifications, which may be useful.

For each of the examples, work with your group to find and fix the bug. Make sure to answer the questions in the lab form for each problem.

  1. ReadQuizScore: What method of debugging did you use? What is the bug? How did you fix the bug?
  2. RepeatInOrder: What method of debugging did you use? What is the bug? How did you fix the bug?
  3. VenmoTracker: What method of debugging did you use? What is the bug? How did you fix the bug?