# lab03: ("lab three") Test-driven development meets turtle graphics, and stars are born

## Goals for this lab

This lab reinforces some ideas from lab01 and lab02

• test driven development
• generalizing functions
• working with Turtle Graphics

## Step by Step Instructions

### Step 0: Get together with your pair partner

You may continue with the same pair partner you had from lab01/lab02, or you may choose a new pair partner for lab03

Either way, please make a posting to the Lab03--Register pair partners here before proceeding with the rest of the lab.

### Step 1: Make sure you both understand the Unit Circle

Both you and your pair partner need to understand the basic concepts of the Unit Circle in this section.

Read through them together, and make sure you do.

In this lab, you'll be working with the unit circle, a concept from trigonometry that will help us in drawing polygons and stars using Turtle Graphics.

I will assume you are familiar with the unit circle, and might just need a refresher course. (If you are truly seeing the unit circle for the first time, you may want to come to your instructors office hours for a crash course.)

#### Unit Circle Basics

The unit circle is a circle with radius 1—i.e. one unit of measurement, e.g. 1cm, or 1m, or 1inch—hence the name unit circle. (Sometimes, instead, we draw a unit circle with radius r, where r is a variable.)

The unit circle is labeled with angles that range from 0 degrees to 360 degrees (which is all the way around the circle.) However, we typically label the unit circle with angles in radians instead of degrees. This angles range from 0 radians to 2π radians. All the way around the circle is 2π radians.

The points on the unit circle at 0, π/2, π and 3π/2 are (1,0), (0,1), (-1,0), and (0,-1), respectively, as shown in the left hand figure below. The right hand figure shows that sometimes we draw circle where the radius is given by r, instead of being exactly 1.

#### Finding a point on the unit circle

We can find the (x,y) coordinates any point on the unit circle if we know the angle, by using some simple trigonometry properties—in particular, the first two of the well known SOHCAHTOA formulas:

• sine is opposite over hypotenuse
• cosine is opposite over hypotenuse

With these in mind, we can see that in the pictures below:

cos is adjacent/hypotenuse, which is x/r, therefore: cos (θ)  = x/r, and therefore x = r cos (θ)
sin is opposite/hypotenuse, which is y/r, therefore: sin (θ)  = y/r, and therefore y = r sin (θ)

Now consider just four more pictures of the unit circle—I promise, these are the ones that will lead us into the Python coding!

 3 points distributed evenly around the unit circle 5 points distributed evenly around the unit circle 6 points distributed evenly around the unit circle 8 points distributed evenly around the unit circle

#### The key points you must understand before going further

• Generalizing the idea shown in the four pictures above, we have a unit circle with n points, labeled 0 through n-1, distributed evenly around the unit circle.
• We can speak of "point i" of these n points, e.g. point 0, or point 3, or point 6.
• If we wanted to draw a circle like this, and make it exact, we might need answers to questions like these:
• In the circle with 5 points what are the x and y coordinate of point 3?
• In the circle with 8 points, what are the x and y coordinates of point 6?
• Those questions can be answered using the formula x = r cos(θ) and y = r sin (θ)

To be able to answer those last questions, we will write two Python functions called:

• ithOfNPointsOnCircleX(i,n,r)
• This function returns the x coordinate of point i on a circle with n points, and radius r
• ithOfNPointsOnCircleY (i,n,r)
• This function returns the y coordinate of point i on a circle with n points, and radius r

You are now ready to look at some Python code!

### Step 4: Decide whose account you are going to work in

Note: DO NOT share passwords with each other. That is a violation of your account agreement, and can result in suspension of your computing privileges at UCSB.

Instead, what you should do is:

• Decide whose account you are going to work in for today's work session
• At the end of every work session, copy your work to the other person's account
• That way, if your pair partner gets hit by a bus, you can continue working without him/her—you aren't 'out of luck'.

Here's how to copy files from one account to another:

Let's suppose that you did all the work in person1's account, and you now want to copy that into person2's account.

1. Person2 should log in. You can log in on a separate computer, or just use one of the terminal windows and use the command: ssh person2@csil.cs.ucsb.edu
2. Person2 cd's into their ~/cs8 directory
3. Person2 types this command
scp -r person1@csil.cs.ucsb.edu:cs8/lab03 lab03.snapshot.date.time
• replace person1 with person1's CSIL username (e.g. jsmith)
• replace date.time with the date and time (e.g. Aug12.1.15pm)
• don't include any slashes or spaces in the date.time string—it must be a valid part of a filename--periods and dashes are ok though.
• Example: scp -r fredjones@csil.cs.ucsb.edu:cs8/lab03 lab03.snapshot.aug12.1.15pm
4. After you type this command, you'll be prompted for a password. Person1 should type his/her password.
• Don't share the password, just have person1 type it in person2's window.
5. If it works, there will now be a directory called lab03.snapshot.date.time in person2's directory that is a complete copy of the ~/cs8/lab03 directory from person1's account.
• Please read the "final thoughts" below so that you understand what the proper use of this process it—it is a powerful command, but it has the potential to be abused. With great power comes great responsibility.

It is only necessary for one of you to submit the work via turnin, as long as both names are in each file.

But, if you are the person whose account is not the one from which the turnin step is done, be SURE that your name appears! You need to work carefully with your pair partner to avoid misunderstandings and problems.

Some final thoughts on this step:

• In this class pair programming is permitted on some assignments.
• The scp command above could be used to copy code from one account to another on assignments where you are not permitted to work together—but that would be wrong.
• So don't do that.

### Step 5: Create a directory for lab03 on one of your accounts.

First, create a directory (folder) called lab03, inside your cs8 folder, which is in turn, inside your home directory.

A short way to say that is: create a directory ~/cs8/lab03

• In Unix, the ~ symbol (tilde), when it stands by itself, is often used as an abbreviation for "your home directory".
• So, ~/cs8 is "cs8 inside your home directory", and ~/cs8/lab03 is "lab03, inside cs8, inside your home directory".

There are two ways to do it:

• Use a terminal window, and use the cd and mkdir commands, or
• Use the graphical user interface—pointing and clicking—to create a new folder

If you've forgotten how, consult the instructions for lab00. If you still can't figure it out, you may ask a classmate, or the TA or instructor for help.

(Note: This is the last time you'll get the detailed version—next lab, you'll just get the instruction "create a ~/cs8/lab04" directory, and you'll be expected to know that to do.)

#### Reminder, for midterm 2:

For midterm 2: be able to explain the difference between ~pconrad/cs8 and ~/pconrad/cs8
It is explained at the corresponding step to this one in lab02.

### Step 6: Bring up IDLE, and a window for function definitions

To bring up IDLE, type this command in the Terminal window, just like we did last week:

`	~pconrad/cs8/cs8idle`

When you do, you should see the IDLE program come up. The window that appears should have the Python Command prompt (>>>) in it.

Next, in IDLE, select "File=>New Window" to open a new "untitled" window for Python code.

When it comes up, click and drag the window by its title bar over to the right of your Python Shell window.

Here's what that looks like:

 Selecting File=>New Window The "untitled" window appearing Dragging the windows so they are side-by-side

Once you've opened that file, add a comment to the top of your file like this one (substituting your own name and the current date in the proper spot):

```# lab03.py for CS8 lab03,  08/12/2009
# By Agnes Nitt and Jason Ogg, based on functions originally by P. Conrad
# Some functions to draw stars and polygons```

Then, save it under the name lab03.py

Note: This is the last time you'll get detailed instructions about this too! Next week, I'll just say: open IDLE, bring up the New Window, save the file (substituting your own name), and start by putting a header comment at the top, with your name(s), date, the name of the assignment, and a one line description of what the file is for.

Now proceed with the next step.

### Step 7. Copy my starting point file into your file

The starting point for this week's lab can be found at this link:

Open that link, and copy the contents into the window you opened for your lab03py file.

#### Adjust the lines at the top

Near the top of the file, there are some lines such as:

import sys; sys.path.append("/Users/Shared/cs8")

or

import sys; sys.path.append("C:/cs8")

These lines may need to be commented or uncommented depending on whether you are

• working in Cooper/CSIL
• working on your own Mac
• working on your own Windows PC

Read the instructions, and do what is needed before running the file

### Step 8. Run the file for the first time

Then, choose Run => Run Module, and see the output.

It should look something like this:

```>>> ================================ RESTART ================================
>>>
Test ithOfNPointsOnCircleX test 1 failed! expected result: 1 actual result: -1.0
|difference|: -2.0 tolerance: 0.001
Test ithOfNPointsOnCircleX test 2 failed! expected result: 0 actual result: -1.0
|difference|: -1.0 tolerance: 0.001
Test ithOfNPointsOnCircleX test 3 passed (within tolerance of: 0.001)
Test ithOfNPointsOnCircleX test 4 failed! expected result: 0 actual result: -1.0
|difference|: -1.0 tolerance: 0.001
Test ithOfNPointsOnCircleX test 5 failed! expected result: 1 actual result: -1.0
|difference|: -2.0 tolerance: 0.001
Test ithOfNPointsOnCircleX test 6 failed! expected result: -0.5 actual result:
-1.0 |difference|: -0.5 tolerance: 0.001
Test ithOfNPointsOnCircleX test 8 passed (within tolerance of: 0.001)
Test ithOfNPointsOnCircleY test 1 failed! expected result: 0 actual result: -1.0
|difference|: -1.0 tolerance: 0.001
Test ithOfNPointsOnCircleY test 8 failed! expected result: 1.73205080757 actual
result: -1.0 |difference|: -2.73205080757 tolerance: 0.001
>>>
```

We see that there are a bunch of tests, and all of them are failing.

So, based on our experience in lab02, we know what to do—we can get right down to work. Here's what to do:

1. In the file, find the stub of the ithOfNPointsOnCircleX() function.
2. Directly under it, you'll see some test cases—but not all the test cases are complete. Test case number 7 for the ithOfNPointsOnCircleX needs you to finish it, using your knowledge of the unit circle.
• Ask yourself, in test case 7, what is the value of n? That is, how many points are on this circle?
• Ask yourself, what is the value of i? That is, which point are we trying to find?
• With that information, figure out: what should the x value of that point be?
• Fill that in for the test case.
3. Then, run the file again, and you'll see that ithOfNPointsOnCircleX now has eight test cases. They are still all failing, but you should have a much better idea of how to fill in the formula, now that you've figured out one of the test cases for yourself.
4. So, now, replace the stub of ithOfNPointsOnCircleX with the correct formula. Now all eight test cases should pass.
5. Do the same for ithOfNPointsOnCircleY: first fix up all the test cases that need fixing up.
6. Then, and only then, replace the stub with the correct formula. Now that all your test cases are passing, you are almost ready for the graphics part of this lab!
7. Before you move on, though, take a moment to clean up any @@@ type comments between the start of the file, and the end of the test cases for ithOfNPointsOnCircleY. You may like to use the Edit / Find menu option to look for @@@. This can make finding these a lot easier.

We are ready for Step 9.

### Step 9: Finishing up the drawPolygon function

Now, locate the drawPolygon() function. This function is almost, but not quite complete.

First take a moment to read over the function and understand how it works

• Note that this function uses Turtle Graphics, but in a different way than we have seen so far.
• So far, the Turtle has always moved "relative" to where the Turtle is now, e.g. forward(), backward(), right(), left(). These are "relative" movements.
• In this function, we tell the turtle exactly where to go in the Cartesian plane—we call this using "absolute" movements.
• The goto() function takes two parameters, x and y, which indicate exactly where the turtle should go.
• The setheading() function takes one argument, which is an angle in degrees that the turtle should face. The angles are the same as those on the unit circle.
• Notice the use of the for loop and the range function to draw all the lines—or almost all the lines—on the polygon.

Just below the drawPolygon function, there is a tryIt() function. This is a function that starts out with every line commented out except for the one that creates a Turtle named Sheila.

You can "uncomment" one line at a time to see various polygons being drawn. Uncomment one of the lines, run the file and try typing tryIt() at the Python Shell Prompt (>>>).

You'll notice that you get a polygon that is missing one side.

Now, fix the drawPolygon function. There are at least two ways to go about it:

• One way is to find the location in the definition of drawPolygon indicated by @@@, and add a line of code there.
• Another way is to adjust some other part of the file. Either method is fine, as long as the result ends up drawing a regular polygon, according to the "contract" in the comments that appear just before the function.

Once drawPolygon is working, move on to drawStar. Try uncommenting the lines in tryIt() one at a time that call drawStar(). You should see that the call when n=3 does nothing, but the call when n=5 or n=6 will give you a five or six pointed star.

Once that is all working, you are ready for step 10

### Step 10: Generalizing the drawStar function

The drawStar function has one drawback: although (0,0) doesn't exactly appear in the function, in a sense the "idea" that the star is drawn centered at (0,0) is nevertheless hard coded in the drawStar function. To make the function more general, what we need to do is add parameters x and y, and then add those values in, every time we make a call to the "goto" function of the Turtle.

Find the place in the file where there is a comment indicating you should add the function drawStarAtXY().

Read the comment, and then follow the instructions there to create this function.

Once you've coded it, you can test it by running the function:

testDrawStarAtXY()

If it works, you should see the stars that appear in this picture:

When you get this, you may move on to the next step—but first, do a visual inspection of your code to remove any remaining @@@ comments in the part you've finished.

### Step 10: Generalizing the drawPolygon function

Now, do exactly the same thing for drawPolygon that you did for drawStar. You'll find comments for a drawPolygonAtXY() function, and a testDrawPolygonAtXY() function waiting for you in the file.

The finished product should look like this:

When you get this, you may move on to the next step—but first, do a visual inspection of your code to remove any remaining @@@ comments in the part you've finished.

### Step 13: Uncomment the call to the go() function

You'll see a go() function near the bottom of the file that just calls the two test functions you've already been working with. There is a function call to go() already there. Just uncomment and test one last time. You should get this as your output:

### Step 14: Check over your program to see if it is ready to submit

Before you submit your assignment, check these things:

• Did you remove all the @@@ comments, and do what they indicated you should?
• Do all of your test cases pass?
• Does your drawing look like the final stage picture?
• Is your file lab03.py inside the ~/cs8/lab03 directory on the Cooper or CSIL machines?
• Finally, to maximize your chances of getting a good grade, look over the grading rubric (near the end of this web page), and make sure that you did everything called for there.

### Step 15 : Submit your assignment using the turnin program on CSIL

To submit your assignment, you need to bring up a terminal window on CSIL.

• Go to a shell prompt on csil, navigate to a directory one level higher than your lab03 directory, and use the command turnin lab03@cs8 lab03 to submit the files in your lab03 directory. (If you aren't sure how, look at the more detailed instructions in lab02)

Each member of a pair (or trio) should submit the same file—you can use email to transmit the file between your accounts.

Later, I'll show you a more effective way: using the scp command to copy files directly from one account to another.

## Evaluation and Grading Rubric (300 pts)

• Professional software documentation practices
• (10 pts) Naming the file lab03.py
• (10 pts) Having a comment at the top of the file that complies with the instructions
• Writing test cases
• (10 pts) Completing ithOfNPointsOnCircleX test case 7
• (60 pts) Completing ithOfNPointsOnCircleY test cases 2 though 7 (10 points each)
• Replacing a stub with real code
• (20 pts) Replace the stub for the ithOfNPointsOnCircleX function so the test cases pass,
• (20 pts) Replace the stub for the ithOfNPointsOnCircleY function so the test cases pass
• Fixing broken code
• (20 pts) Fix the drawPolygon function so it operates properly
• Generalizing code with hard-coded functionality
• (25 pts) Generalizing the drawStar function so that it can draw a star anywhere in the Cartesian Plane
• (25 pts) Generalizing the drawPolygon function so that it can draw a star anywhere in the Cartesian Plane
• Following Instructions
• (10 pts) Having an uncommented go() function that tests your submission as soon as it is run
• (40 pts) Submitting on time and according to instruction
• (30 pts) Making a post on the Gauchospace forum with your pair's names and the times you can work together

### Due Date: Friday, October 15, 5pm

But: you are encouraged to finish it sooner!
In particular, you are encouraged to work on it and try to finish it before the 1st midterm exam (E01) on Tuesday October 12.

Although you are not "responsible for" the "new" material on this lab for E01, nevertheless, working on this lab is a great way to study for the midterm. All of Computer Science is cumulative, and you'll be working with, and building on, all of the things that are on the upcoming midterm exam.

This assignment will be accepted "late" with a 40 point penalty in the period between Friday October 15th at 5:01pm and Wednesday October 20th at 11:59pm. After that, no credit may be earned for this lab---a zero will be recorded.

Copyright 2010, Phillip T. Conrad, CS Dept, UC Santa Barbara. Permission to copy for non-commercial, non-profit, educational purposes granted, provided appropriate credit is given; all other rights reserved.