Warmup

Part A: Warmupgram

In Lab 4, you will write a program that uses a while loop to ask the user which filter they would like to apply to a picture (like on, e.g., Instagram). In the Warmup, you will implement two filters, with the goals of getting used to important functions in the picture module and testing your program on a simulated desktop. These filters will be in a separate file for the Warmup, then you can import them into the main lab’s file later.

Flow of Execution

Before you write any new code, take a look at the overall program structure given in the starter code for warmupgram.py. Notice the code at the end of the file which loads the crayons.jpg test image, applies the two filters you will implement as part of the Warmup, and then shows the filtered test image. Talk through the flow of execution out loud (“What would Python do?”) with your Warmup partner before continuing.

Using the Live View

This lab’s Codespace has been set up to have a live view of the images as you use the filters. In contrast to previous labs where the graphics output was a static image that appeared as a new file in the repository, this lab’s output will be displayed as a software application on a simulated desktop. To access this live view, follow these steps.

  1. Open your Codespace as you normally would.

  2. In the Terminal pane, click the Ports tab, and then click on port 6080. Move your cursor over to the two rectangles with the magnifying glass and click on that icon. Another tab should open next to your code.

  1. Once this opens, click the Connect button.
  1. If prompted, enter csci into the password box.
  1. Run your program the way you normally would and the image will pop up in the window on the right.
  1. Click on the heading of the photo where it says tk and drag it into the middle of the window to see the whole photo. (If you are running this for the first time with warmupgram.py, the window will show a blank white canvas because we have not yet implemented any filtering functions.) When you want to stop the program from running, click the small x in the corner of the window to stop the file. You can leave this simulated desktop tab open even when not running a file. If you start running a file, it will appear in the panel – You do not need to go through the Ports tab again.

Grayscale

The first filter you’ll implement is grayscale. Below, you’ll see an image of crayons, as well as the grayscale version.

The first thing you’ll need to do is get an image loaded and displayed so you can see the effects of your filter. To start, we’ll just load and display an exact copy of the original (color) image above.

ReadMe

What is the difference between warmupgram_func and warmupgram_run?

warmupgram_func.py: Contains all the functions that edit the image in cool ways. This file can be reused later by being imported into the imagegram.py. No need to worry about this now.

warmupgram_run.py: Contains the code needed to display the image, and is already set up to look for your functions in warmupgram_func.py.

Check out warmupgram_func.py for some starter code. To get the grayscale() function working, you must first complete the copy() function. It takes as input an image object like the one loaded by the starter code, and creates a new image object, called imagecopy. Each of your filter functions should have different variables to store the original image and the filtered image.

Some functions you’ll want to know about:

  • picture.get_green(image,x,y) returns the green value of the pixel in image at location (x,y). It will be returned as a number between 0 and 255.
  • picture.get_blue(image,x,y) and picture.get_red(image,x,y) do similar things for the colors blue and red.
  • picture.set_green(image,x,y,val) changes the green value of the pixel in image at location (x,y) to val. val must be an integer between 0 and 255.
  • picture.set_blue(image,x,y,val) and picture.set_red(image,x,y,val) do similar things for the colors blue and red.

Alternatively, you can use red,green,blue = picture.get_pixel(image,x,y) and picture.set_pixel(image,x,y,(rval,gval,bval)) to get/set all three values simultaneously. The RGB values returned by picture.get_pixel() are stored in three variables: red, green, and blue, which you should feel free to rename.

To write your copy() function, you’ll need to use picture.get_ and picture.set_ functions to copy all the pixel data from image to imagecopy before returning imagecopy.

Once this function is complete, run python3 warmupgram.py in the terminal, then check the live view in the simulated desktop as explained above. The application window on the simulated desktop should now display a replica of the original image. Now all you have to do is add some code in the middle of the grayscale function that overwrites the pixel values with their corresponding grayscale values. An explanation of how to do this is included in the comments.

Reminder

After you complete this function and add your notes to WARMUP.md be sure to commit and push your changes!

Vertical Flip

For this task you will complete the vertflip() function in warmupgram.py, which turns an image upside-down. With your partner, draw a diagram to help you figure out the variable/expression needed for this filter: For every coordinate (x, y) in the original image, what should the corresponding pixel in the image copy be set to?

In this filter the copy() function is even more important: if you were to use picture.get_ and picture.set_ functions directly on the original, you’d end up overwriting the values of pixels you’ll need later.

Once you’ve created a duplicate image with your copy() function, use the original as a reference as you go through and set the pixels in image to be upside-down. Keep the original untouched as a reference, and design your program so that imagecopy is the flipped picture. In the lab, you’ll continue to pass and return image objects. For this lab, you should always “read” from the original image and “set” the filtered pixel values in your imagecopy.

Reminder

After you complete this function and add your notes to WARMUP.md be sure to commit and push your changes!

Part B: Debugging Practice

For this week’s debugging practice, you’ll consider some function-related bugs that you’re likely to encounter at some point as programmers. Solve each problem by first thinking on your own for a few minutes, then discussing what you figured out with your partner.

You’re going to be debugging three calculator programs today. They were written by someone who didn’t seem to realize that you could just do basic calculations in the console. Instead, each of the three programs runs a while loop, which asks the user whether they want to multiply, exponentiate, or quit. Multiplying should ask for two numbers, say, x and y, and print their product. Exponentiating should ask for two numbers, a base and an exponent, and raise the base to the power of the exponent. Unfortunately, none of the three programs, calc1.py, calc2.py, or calc3.py does both tasks successfully.

For each program, decide on some test cases, and run the program on those test cases. You should make sure to try both multiplication and exponentiation (though both aren’t necessarily broken), and make sure that your test results are different when the inputs are switched. See if you can figure out what the bugs are in each program and how to fix them. Better yet, try to understand what the person who wrote the code might have been confused about. Write your explanations for each program in WARMUP.md.

ReadMe

The while loop for each program is correctly implemented; you should be looking for bugs with the functions and their usage.

Reminder

Be sure to commit and push your changes after you debug each function and add your notes to WARMUP.md!