CS21 Lab 2: Multiples

Due Saturday, September 17, by midnight

Programming Tips

As you write programs, use good programming practices:

  • Use a comment at the top of the file to describe the purpose of the program (see example).

  • All programs should have a main() function (see example).

  • Use variable names that describe the contents of the variables.

  • Write your programs incrementally and test them as you go. This is really crucial to success: don’t write lots of code and then test it all at once! Write a little code, make sure it works, then add some more and test it again.

  • Don’t assume that if your program passes the sample tests we provide that it is completely correct. Come up with your own test cases and verify that the program is producing the right output on them.

  • Avoid writing any lines of code that exceed 80 columns.

    • Always work in a terminal window that is 80 characters wide (resize it to be this wide)

    • In vscode, at the bottom right in the window, there is an indication of both the line and the column of the cursor.

Are your files in the correct place?

Make sure all programs are saved to your cs21/labs/02 directory! Files outside that directory will not be graded.

$ update21
$ cd ~/cs21/labs/02
$ pwd
/home/username/cs21/labs/02
$ ls
Questions-02.txt
(should see your program files here)

Goals

The goals for this lab assignment are:

  • Draw images with code

  • Practice with Processing’s coordinate and colors systems

  • Learn to iterate over data using for loops

  • Practice using the range function

  • Compare different loop designs

Processing Python — Graphics

For this lab we’ll use the Processing version of Python (processing-py.sh) for its graphics, but only the following Processing commands will be used:

size(WIDTH, HEIGHT)      # first thing called to setup the window
dist(X1, Y1, X2, Y2)     # compute the distance between (X1, Y1) and (X2, Y2)

Drawing

circle(X, Y, DIAMETER)   # draw a circle of a certain DIAMETER at (X, Y)
line(X1, Y1, X2, Y2)     # draw a line from (X1, Y1) to (X2, Y2)

processing line

Color

background(GRAY) or background("HEXSTRING")   # paint the canvas with color
fill(GRAY)       or fill("HEXSTRING")         # select color for interior
stroke(GRAY)     or stroke("HEXSTRING")       # select color for outline
noFill()                                      # don't fill
noStroke()                                    # don't outline

processing grayscale

However, check out the reference page for a complete list of all the fun things you can do!

1. Processing Warm-up

We were trying to refactor the following program to use a for-loop and save some keystrokes, but something went terribly wrong: HELP!

# warmup02-00.py
def setup():
    size(400, 400)
    background(255)
    stroke(0)
    fill(255)
    circle(200, 200, 225)
    circle(200, 200, 200)
    circle(200, 200, 175)
    circle(200, 200, 150)
    circle(200, 200, 125)
    circle(200, 200, 100)

Here was our attempt at a for-loop:

# warmup02-01.py
def setup():
    size(400, 400)
    background(255)
    stroke(0)
    fill(255)
    for diam in [100, 125, 150, 175, 200, 225]:
        circle(200, 200, diam)

Trace the two programs by hand on a piece of paper, and then type and run them on the computer. Do these programs do the same thing, i.e., are they behaviorally equivalent? Explain your findings in warmup.txt.

$ processing-py.sh warmup02-00.py
$ processing-py.sh warmup02-01.py

In processing mode we’ll use setup() and draw() instead of main. Those functions get called automatically for us: setup(), once at the start, and draw(), 60 times per second. Because this lab relies on graphics, it works best run on the lab machines or using the Processing IDE, i.e., the standard VS Code remote setup won’t work.

2. Circle

The sketch below draws a circle that changes size based on your mouse. Fill in the lines to compute the circumference (\(2 \pi r\)) and area of the circle (\(\pi r^2\)).

$ processing-py.sh circle.py

circle image

def setup():
    size(600, 600)

def draw():
    background(24)
    radius = dist(mouseX, mouseY, width/2, height/2)
    circle(width/2, height/2, 2*radius)
    circum = 0             ## FILL THIS IN
    area = 0               ## FILL THIS IN
    text("c = " + str(circum), 25, 25)
    text("a = " + str(area), 25, 50)
Using Math Functions

Python comes with a collection of mathematics tools in something called the math library. But you won’t see them unless you import the library.

For example, there is a variable called pi in there that approximates π.

import math
print(math.pi)

results in the output

3.141592653589793

And there are bunch of functions like sqrt, sin and cos:

math.cos(math.pi))

which prints:

-1.0

3. Vinyl: How much music?

The sketch below depicts a vinyl record using a series of circles. Real vinyl records are spirals, not a series of concentric circles, but let’s assume they are circles for the time being. Also assuming each pixel is a second of play-time, compute how much total music is on the record.

$ processing-py.sh vinyl.py

vinyl image

def setup():
    size(600, 600)

def draw():
    background(24)
    stroke(196)
    noFill()

    radius = dist(width/2, height/2, mouseX, mouseY)

    t = 0
    for diam in range(0, int(2*radius), 20):
        circle(width/2, height/2, diam)
        t = 0 # FILL THIS IN
    text("FILL THIS IN", 25, 25)

For example, consider the warm-up exercise (part 1) above. The outer track has a diameter of 225 pixels, so the circumference would be 706.85 (225 × π). Then, to find the total length, add all the track lengths together. There are 6 tracks, so we would have 225 × π + 200 × π + 175 × π + 150 × π + 125 × π + 100 × π seconds of music. Doing that computation results in 3063.05 seconds, or 51.05 minutes.

When you run your program, display the amount of music in seconds (and minutes).

4. Gradient

Recreate the picture below using a series of vertical lines. You can use stroke() to change the color of the line. The window should be 256 pixels wide by 256 pixels high. Use the range function.

stroke(0)
line(0, 0, 0, 255)
stroke(1)
line(1, 0, 1, 255)
stroke(2)
line(2, 0, 2, 255)
...
stroke(255)
line(255, 0, 255, 255)
$ processing-py.sh gradient.py

gradient image

5. Rainbow

Recreate the picture below using a series of circles located at the bottom of the window. The window should be 400 pixels wide by 300 pixels high.

You must use a for loop in your solution!
$ processing-py.sh rainbow.py

rainbow image

Here is a list of colors that might be useful:

rainbow = ["#FF0000", "#FF7F00", "#FFFF00", "#00FF00",
           "#0000FF", "#4B0082", "#9400D3", "#FFFFFF"]

But you can pick your own colors too!

6. BONUS: String Art

Using a series of lines, recreate the picture below. The picture should be correct regardless of the window’s width and height, and it the mouse should change the number of lines displayed.

$ processing-py.sh string.py

string art with 20 lines

string art with 200 lines

Answer the Questionnaire

Each lab will have a short questionnaire at the end. Please edit the Questions-02.txt file in your cs21/labs/02 directory and answer the questions in that file.

Once you’re done with that, you should run handin21 again.

Submitting lab assignments

Remember to run handin21 to turn in your lab files! You may run handin21 as many times as you want. Each time it will turn in any new work. We recommend running handin21 after you complete each program or after you complete significant work on any one program.

Logging out

When you’re done working in the lab, you should log out of the computer you’re using.

First quit any applications you are running, like the browser and the terminal. Then click on the logout icon (logout icon or other logout icon) and choose "log out".

If you plan to leave the lab for just a few minutes, you do not need to log out. It is, however, a good idea to lock your machine while you are gone. You can lock your screen by clicking on the lock xlock icon. PLEASE do not leave a session locked for a long period of time. Power may go out, someone might reboot the machine, etc. You don’t want to lose any work!