# CS21 Lab 6: Functions and Graphics

Due Saturday (March 4) before midnight

This lab assignment requires you to write programs using objects from the Zelle graphics library. There is also a written component to this lab which you should turn in at the start of class on Thursday, March 2 or Friday, March 3, depending on your section. The written component, which asks you to trace a program and draw a stack diagram, is at this link. Print out the PDF and write your answers directly on the sheet.

Goals

The goals for this lab assignment are:

• Write a program that uses objects, methods, graphics, animation, and functions.
• Practice writing and using functions that return lists or take lists as input.
• Gain a better understanding of mutation.
Programming tips/requirements
• Same as always: comments at the top and for each function, good variable names, write and test incrementally.
• Don't hard-code values! Define variables, like width and height, then specify positions, sizes, lengths, etc. as a fraction of the width and height.
• We have provided some images below. It's okay if your images look a little different, as long as they still satisfy the program requirements.
• If you are working remotely, see our help page on remote access.
• When using raw_input() to ask the user for input, doing that before setting up the graphics window is often easier (less clicking back and forth between windows).
• don't forget to run update21 and put your programs in your cs21/labs/06 directory.
busybugs.py

For this assignment we will use the graphics library to construct a program, busybugs.py, that builds, draws, moves, rotates, and animates bugs. We have described a number of functions that we want you to write. For each function you should follow the guidelines regarding input parameters and the return value. For each function you should also write a comment detailing the purpose, parameters, and return value, as in this example.

1. Create a Bug

Open a file named busybugs.py and write a function createABug(center, radius, window).

createABug(center, radius, window) creates and then draws an bug in the given window at a specific location (center) with a specific scale (radius). Your bug must be comprised of only circles, but you can choose the number of circles, their colors, and their relative positions.

The createABug function has the following parameters:

1. center: A Point object indicating the location in the window for the center of the bug.
2. radius: The radius of the largest circle in the bug. All other circles in the bug should be scaled in proportion to this radius. Thus, a bigger radius will draw a bigger bug.
3. window: A GraphWin object.
The createABug function should return a list of the Circle objects that together make up a single bug. The first Circle object in the list (at index 0) should be centered at center.

For symmetrical features (such as eyes or ears), remember you can use the clone method to make a copy of the original shape, and then use the move method to place it at the desired location.

Once you have your createABug function implemented, test it by calling it from the main function with a few different values passed in for the center and radius.

Below are three examples of bugs. Feel free to make your own, but remember that bugs should be comprised of only circles (to later facilitate rotation).

2. Make a Bug Crawl

Write a function crawlBug(bug, dx, dy) that moves a bug by the specified x and y distances. Remember that to move a bug, you must move all circles in the list that makes up the bug. NOTE: this movement is not animated. The crawlBug function has the following parameters:

1. bug: A list of Circle objects describing a bug.
2. dx: The distance to move in the x-direction.
3. dy: The distance to move in the y-direction.

The crawlBug function should not return anything. It just mutates each Circle in the list.

Once you have written this function, add some code to main to test your new function.

3. Make a Bug Spin

Write a function spinBug(bug, degrees) that rotates the given bug the given number of degrees about its center. NOTE: this rotation is not animated. The parameters for spinBug are:

1. bug: A list of Circle objects describing a bug.
2. degrees: The number of degrees to rotate the bug.
The spinBug function should not return anything. It just mutates each Circle in the list.

The bug should be rotated around the center of the first Circle object in bug. This first circle is the main circle. Using the formula given below, you will rotate all the other circles around the the center point of the main circle.

• First, identify the main circle's center coordinates (xc, yc) using the getCenter(), getX(), and getY() methods.
• Next rotate each body part other than the main circle as follows:
• For each body part identify the coordinates of its center, (x, y).
• Now calculate dx and dy using:
dx = x - xc
dy = y - yc

• Finally, to rotate this part by an angle of t radians around the main center point (xc, yc), you must move the part by an amount (mx, my) defined as follows:
mx = dx * (cos(t)-1)  -  dy * sin(t)
my = dx * sin(t)      +  dy * (cos(t)-1)


In the above formulas we are using the functions sin and cos, which must be imported from Python's math library. These functions expect the angle to be in radians. You can use the python math function radians to convert the angle from degrees to radians (e.g., t = radians(degrees)).

Once you have completed this function, test it in your main function. For example, after you draw a bug, call this function to change a bug's orientation in the graphics window, as in the example below.

4. Animate Bugs

Once all of the required functions are working correctly, create an animation with your bugs in main. Feel free to write additional functions as needed.

Your main function should satisfy the following requirements:

• Uses the function createABug to construct at least 3 bugs in the graphics window.
• Uses the functions crawlBug and spinBug along with the sleep function (from the time library) to create an animation of the bug.
• Wait for a mouse click to begin the animation.
• After the animation, wait for a mouse click to end the program.

The video below shows an example animation that satisfies these requirements:

Extra Challenge - Synchronized Bugs

If you have the time and the inclination, attempt this extra challenge as a way of getting practice with the append method for lists. This is just for fun, no bonus points will be given.

Modify your program so that it begins by asking the user (via raw_input) how many bugs they want to see in the animation. Then open the graphics window and wait for the user to click that number of times, placing a randomly-sized bug at each of the locations clicked. After these clicks, the newly-created bugs should go into a synchronized dance, in which a series of crawls and rotations happen in unison. (See video below.)

To facilitate this, you should put all the bugs into a single list stored in a variable called bugs. Because each bug is itself a list of Circle objects, bugs will be a list of lists of circles. bugs would start as an empty list, and after each user click you would use append to add the newly-created bug to the end of bugs.

You may also want to create functions crawlAllBugs(bugs, dx, dy) and spinAllBugs(bugs, degrees) that take in the list of bugs and perform the specified motion for each bug in the list. crawlAllBugs would itself call crawlBugs and similarly spinAllBugs would make use of spinBugs.

Submit