By the time you have completed this lab, you should be able to
This lab will also reinforce some lessons from lab01
As with lab01, lab02 is a Pair Partner lab.
Just like last time, we are asking you to find times that you can work together outside of class, and make a commitment to those times—and post those times on a discussion board on Gauchospace.
If you do not have a pair partner, please contact your TA and/or instructor for assistance.
Next, you need to choose an initial driver and a navigator. You will start your work in the driver's account—and switch half way through. When you switch, you'll copy the files just to make sure you both have a copy of the files in each of your accounts.
The driver should log on to her/his CSIL account just as you did for lab00 and lab01.
Note: these instructions assume you are working in Cooper or CSIL—if you are working on your own PC or Mac, you'll need to adapt these instructions to your situation.
First, create a directory (folder) called lab02, inside your cs8 folder, which is in turn, inside your home directory.
A short way to say that is: create a directory ~/cs8/lab02
There are two ways to do it:
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: eventually, I'll stop spelling this out in so much detail—I'll just say: create a ~/cs8/lab03 directory, for example, and expect that you'll know how to do that. For at least one more lab, though, I'll hold your hand through the process. By the time you get to cs24 and beyond, you'll likely be expect to just know that you should create a separate folder for each of your assignments.)
We learned up above that ~ by itself is a symbol for your home directory.
As an example, ~/cs8/lab02/myFunctions.py means: go into my home directory, then into cs8, then into lab02, then look at the file myFunctions.py
If we put a name after the tilde, we can access someone else's home directory. So, ~pconrad/cs8/cs8idle means "look for a file cs8idle inside a directory cs8 inside pconrad's home directory".
Note that ~pconrad/cs8/cs8idle and ~/pconrad/cs8/cs8idle are not the same.
For the exam: be able to explain the difference between ~pconrad/cs8 and ~/pconrad/cs8
To bring up IDLE, type this command in the Terminal window, just like we did last week:
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):
# lab02.py by Agnes Nitt and Jason Ogg for CS8 lab02, 08/12/2010 # Some Example Python Functions
Then, save it under the name lab02.py
Note: eventually, with this as well, I'll stop spelling this out in so much detail—I'll just say: start a new Python file called lab02.py. I'll expect you to know that this means: open IDLE, bring up the New Window, and start by putting a header comment at the top, with your name, date, the name of the assignment, and a one line description of what the file is for.
For at least one more lab, though, I'll hold your hand through the process.
By the time you get to cs24 and beyond, there will be an expectation that you are used to all this—once you've been shown once how to use the basic tools of a programming environment, you'll be able to just bring up those tools, start a new file (with header comment at the top), and get to work.
Now proceed with Step 3.
The next step is to examine a few things about print vs. return.
We are going to define two functions in our function window—both of which calculate the square of a number—i.e. the number multiplied by itself.
One will do it using print, and the other using return.
At first, the two functions will seem to be identical. But as we'll discover, there is a big difference between them.
In the window you created for lab02.py, enter these two function definitions after your comment, so that the file looks like this:
# lab02.py by Agnes Nitt and Jason Ogg for CS8 lab01, 08/12/2010 # Some Example Python Functions
# a function that returns the square of a number def square(x): return (x * x) # a function that prints the square of a number def sqr(x): print (x * x)
Ask yourself—what is the difference between these two functions?
Then, choose the "Run" command from the menu. In your Python shell window, you should see output similar to the following:
>>> ================================ RESTART ================================ >>>
At this prompt, you can now type function calls to the two functions you've defined. Try these:
>>> square(5) 25 >>> sqr(5) 25 >>> square(3) 9 >>> sqr(3) 9 >>>
At the moment, it may appear that there is no difference between return and print—they both do the same thing.
But, then, try this:
>>> square(5) + square(5) 50 >>>
As you can see, the result is 50—because 5 squared is 25, and if you add 25 + 25, you get 50.
But compare this:
>>> sqr(5) + sqr(5) 25 25 Traceback (most recent call last): File "", line 1, in
sqr(5) + sqr(5) TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType' >>>
Here, you get a completely different result! So, clearly, there is a big difference between return and print inside a function.
The difference is this:
square(5) + square(5) becomes
25 + 25, because
square(5) returns the value
5 * 5, i.e.
But, when a function doesn't return anything, the function call gets replaced with a value that has something called "NoneType".
sqr(5) + sqr(5) becomes something like
NoneType + NoneType, and Python doesn't know how to handle that. Yes, the values 25 and 25 get printed, but not in any way that is useful.
This is why we will emphasize writing functions that return values rather than print values—they are generally more useful, because they can be reused inside other expressions.
Try a few more examples to illustrate the idea:
>>> square(3) + square(4)When you think you understand the difference, move on to the next step. If you don't understand the difference, try to figure it out some more—or make a note to ask about it in lecture, or office hours—this is an important concept and will definitely be on the next midterm exam!
>>> sqr(3) + sqr(4)
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
sqr(3) + sqr(4)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'
>>> square(square(2)) 16 >>> sqr(sqr(2)) 4 Traceback (most recent call last): File "", line 1, in
sqr(sqr(2)) File "/Users/bob/Documents/lab02.py", line 11, in sqr print (x * x) TypeError: unsupported operand type(s) for *: 'NoneType' and 'NoneType' >>> square(square(square(2))) 256 >>>
The starting point for this weeks lab can be found at this link:
Open that link, and copy the contents into the window you opened for your lab02.py file.
Then, choose Run => Run Module, and see the output.
It should look something like this:
>>> ================================ RESTART ================================ >>> Test perimRect test 1 passed. Test perimRect test 2 passed. Test perimRect test 3 passed. Test FtoC test 1 failed! expected result: 100 actual result: 194.222222222 Test FtoC test 2 failed! expected result: 0 actual result: 14.2222222222 Test FtoC test 3 failed! expected result: 20 actual result: 50.2222222222 Test areaRect test 1 failed! expected result: 6 actual result: -1 Test areaRect test 2 failed! expected result: 10 actual result: -1 Test areaRect test 3 failed! expected result: 9 actual result: -1 >>>
We can see that three tests passed for the perimRect function, but all the rest of the tests failed. So, we have some work to do.
The idea here is that the function check_expect can be used to test whether a function works correctly or not.
Take a look at the function definition for check_expect.
Look at the code for a moment, and see if you can see this in the code.
def check_expect(testLabel,check,expect): if (check == expect): print ("Test " + testLabel + " passed.") else: print ("Test " + testLabel + " failed! expected result: " + str(expect) + " actual result: " + str(check))There may be a few things here that are unfamiliar:
+here means string concatenation—that is, sticking two strings together.
str(check), this is code to turn numbers into strings so they can be combined into a single message.
check == expectthis is Python code that asks a question—is check equal to expect? If so, the answer is
Trueand if not, the answer is
if/elsestatement is one that asks a true/false question and then has two parts
ifis done only when the answer to the question is
True, i.e, in this case, when the value of
expectare equal to each other
elseis done only when check and expect are NOT equal to each other.
But don't worry too much about those details—the main thing is the big picture. And the big picture is that the
check_expect function is one that helps us test other functions to see if they work properly.
Look in the code you have in your window, and find the following section:
def perimRect(length,width): return 2 * length + 2 * width
This is a function that should return (not print!) the perimeter of a rectangle—the formula is double the length plus double the width.
We then see some "test cases", that look like this:
check_expect("perimRect test 1", perimRect(2, 3), 10) check_expect("perimRect test 2", perimRect(4, 2.5), 13) check_expect("perimRect test 3", perimRect(3, 3), 12)
The idea is that each call to check_expect has three parameters:
"perimRect test 1"—just a label to let us know which test we are doing
perimRect(2,3)that we are checking
You can see that testLabel, check, and expect correspond to the three parameters of the check_expect function definition:
This is always true in Python programming: the parameters in the function call need to correspond exactly with the parameters in the function definition.
So, what's happening in this lab is the following:
Each of the places that you find some @@@ comments, your job is to follow the instructions there, and then remove the comment with the @@@ signs in it.
When your file passes all the tests, and you've correctly removed all the comments that have @@@ lines in them, you are almost finished and ready to submit!
Here's an example of what the finished output would look like (note the additional tests that have been added):
Test perimRect test 1 passed.
Test perimRect test 2 passed.
Test perimRect test 3 passed.
Test perimRect test 4 passed.
Test perimRect test 5 passed.
Test FtoC test 1 passed.
Test FtoC test 2 passed.
Test FtoC test 3 passed.
Test FtoC test 4 passed.
Test areaRect test 1 passed.
Test areaRect test 2 passed.
Test areaRect test 3 passed.
Test areaRect test 4 passed.
Test CtoF test 1 passed.
Test CtoF test 2 passed.
Test CtoF test 3 passed.
Test CtoF test 4 passed.
If you get output like that—and you've replaced all the @@@ comments in your code with the proper stuff, you are almost ready to submit!
But first, do a visual inspection of your code to double check that you did everything you were asked to do... that is Step 5.
Before you submit your assignment, check these things:
To submit your assignment, we use the cd command that we practiced earlier:
-bash-3.00$ cd -bash-3.00$ pwd /cs/student/yourusername -bash-3.00$ cd cs8 -bash-3.00$ pwd /cs/student/yourusername/cs8 -bash-3.00$
When you are in inside your cs8 directory, you are ready for the turnin step.
Type the following at the prompt:
turnin lab02@cs8 lab02
You should be asked if you want to turn in this program. Respond "yes", and then you should get a message indicating that your efforts were successful!
Note: Starting with the next lab, I won't spell this out in so much detail. I'll just say something like
You'll be expected to know what to do. Eventually, even that will be whittled down to:
Due Date: Friday, October 8, 5pm
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.