CS 1110, LAB 3: MODULES AND TESTING First Name: Last Name: NetID:

Similar documents
CS 1110, LAB 3: STRINGS; TESTING

CS 1110, LAB 03: STRINGS; TESTING First Name: Last Name: NetID:

CS 1110, LAB 10: ASSERTIONS AND WHILE-LOOPS 1. Preliminaries

CS 1110, LAB 13: SEQUENCE ALGORITHMS

CS 1110 SPRING 2016: GETTING STARTED (Jan 27-28) First Name: Last Name: NetID:

CS 1110, LAB 1: EXPRESSIONS AND ASSIGNMENTS First Name: Last Name: NetID:

CS1110 Lab 1 (Jan 27-28, 2015)

CS 1110, LAB 2: FUNCTIONS AND ASSIGNMENTS

Lab 3. A Multi-Message Reader

Conditionals & Control Flow

CS1110 Lab 6 (Mar 17-18, 2015)

Intro. Scheme Basics. scm> 5 5. scm>

Lecture 9: July 14, How to Think About Debugging

Lecture 2: Variables & Assignments

PREPARING FOR PRELIM 1

Week - 01 Lecture - 04 Downloading and installing Python

Lecture 3. Functions & Modules

CMSC 201 Fall 2016 Lab 09 Advanced Debugging

Announcements for this Lecture

Lecture 8. Conditionals & Control Flow

Lecture 17: Classes (Chapter 15)

DEBUGGING TIPS. 1 Introduction COMPUTER SCIENCE 61A

Lecture 6: Specifications & Testing

Lecture 3. Functions & Modules

CS 1110 SPRING 2016: LAB 3: PRACTICE FOR A2 (Feb 23-24)

CS Lecture 19: Loop invariants

CS 1110, LAB 2: ASSIGNMENTS AND STRINGS

4.2 Function definitions the basics

Text Input and Conditionals

Section 1: Let s Shake Off the Rust!

Testing and Debugging

CSE : Python Programming. Packages (Tutorial, Section 6.4) Announcements. Today. Packages: Concretely. Packages: Overview

Initial Coding Guidelines

Lecture 4. Defining Functions

CS 1110, LAB 12: SEQUENCE ALGORITHMS First Name: Last Name: NetID:

Programming Assignment III

Software Testing Prof. Meenakshi D Souza Department of Computer Science and Engineering International Institute of Information Technology, Bangalore

Testing is a very big and important topic when it comes to software development. Testing has a number of aspects that need to be considered.

Python for Informatics

Week - 04 Lecture - 01 Merge Sort. (Refer Slide Time: 00:02)

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #29 Arrays in C

Semester 2, 2018: Lab 1

CS Lecture 18: Card Tricks. Announcements. Slides by D. Gries, L. Lee, S. Marschner, W. White

Last Name: First: Netid: Section. CS 1110 Final, December 17th, 2014

6.001 Notes: Section 15.1

The first program: Little Crab

Testing. UW CSE 160 Winter 2016

CSCU9B2 Practical 1: Introduction to HTML 5

Problem 1. Remove consecutive duplicates (6 points, 11 mintues)

Privacy and Security in Online Social Networks Department of Computer Science and Engineering Indian Institute of Technology, Madras

Using IDLE for

Lecture 5. Defining Functions

CS Prelim 1 Review Fall 2018

Black Problem 2: Huffman Compression [75 points] Next, the Millisoft back story! Starter files

CSCI 161: Introduction to Programming I Lab 1b: Hello, World (Eclipse, Java)

CS 112: Intro to Comp Prog

ACORN.COM CS 1110 SPRING 2012: ASSIGNMENT A1

CS1110. Lecture 6: Function calls

Lecture 7: Objects (Chapter 15) CS 1110 Introduction to Computing Using Python

CS1 Lecture 3 Jan. 22, 2018

Lecture 17: Classes (Chapter 15)

CS1110 Lab 5: Practice for A4 (Mar 8-9, 2016) First Name: Last Name: NetID:

Boot Camp. Dave Eckhardt Bruce Maggs

CS1 Lecture 5 Jan. 25, 2019

PYTHON YEAR 10 RESOURCE. Practical 01: Printing to the Shell KS3. Integrated Development Environment

CS 1110 Prelim 1 October 4th, 2012

PREPARING FOR PRELIM 2

CMSC 201 Spring 2019 Lab 06 Lists

CS 1110 Final, December 17th, Question Points Score Total: 100

CMSC162 Intro to Algorithmic Design II Blaheta. Lab March 2019

Compiling with Multiple Files The Importance of Debugging CS 16: Solving Problems with Computers I Lecture #7

Unit Testing In Python

Computer Science Lab Exercise 1

These are notes for the third lecture; if statements and loops.

Programming with Python

Programming Assignment Multi-Threading and Debugging 2

STATS 507 Data Analysis in Python. Lecture 2: Functions, Conditionals, Recursion and Iteration

Who am I? I m a python developer who has been working on OpenStack since I currently work for Aptira, who do OpenStack, SDN, and orchestration

The name of our class will be Yo. Type that in where it says Class Name. Don t hit the OK button yet.

CS 112 Project Basics

XP: Backup Your Important Files for Safety

1 Lecture 5: Advanced Data Structures

Note: This is a miniassignment and the grading is automated. If you do not submit it correctly, you will receive at most half credit.

CS1 Lecture 4 Jan. 23, 2019

Design and Analysis of Algorithms Prof. Madhavan Mukund Chennai Mathematical Institute. Week 02 Module 06 Lecture - 14 Merge Sort: Analysis

CS 1110, LAB 1: PYTHON EXPRESSIONS.

CS Prelim 1 Review Fall 2017

A lot of people make repeated mistakes of not calling their functions and getting errors. Make sure you're calling your functions.

CIT 590 Homework 5 HTML Resumes

CS 1110: Introduction to Computing Using Python Loop Invariants

Writing and Running Programs

There are many other applications like constructing the expression tree from the postorder expression. I leave you with an idea as how to do it.

Chapter 5 Errors. Bjarne Stroustrup

Tutorial: GNU Radio Companion

CSCI 204 Introduction to Computer Science II. Lab 6: Stack ADT

Lab 2 Building on Linux

USING DRUPAL. Hampshire College Website Editors Guide

Fortunately, you only need to know 10% of what's in the main page to get 90% of the benefit. This page will show you that 10%.

Lecture 8: Conditionals & Control Flow (Sections ) CS 1110 Introduction to Computing Using Python

CS1 Lecture 3 Jan. 18, 2019

Transcription:

CS 1110, LAB 3: MODULES AND TESTING http://www.cs.cornell.edu/courses/cs11102013fa/labs/lab03.pdf First Name: Last Name: NetID: The purpose of this lab is to help you better understand functions, and to introduce you to the basics of testing. Adopting a strong testing habit is very important for learning programming, particularly for the first assignment. As a warning, we will tell you right now: the module funcs has errors in it. Do not look for them right away. You should only correct a module when you are told, as we step you through the testing exercise. Lab Materials. We have created several Python files for this lab. You can download all of the from the Labs section of the course web page. http://www.cs.cornell.edu/courses/cs1110/2013fa/labs When you are done, you should have the following four files. demo test.py (a simple script to get started) funcs.py (the buggy module) parse.py (another, optional, buggy module) test funcs.py (a testing script) You should create a new directory on your hard drive and download all of the files into that directory. Alternatively, you can get all of the files bundled in a single ZIP file called lab03.zip from the Labs section of the course web page. 0.1. Getting Credit for the Lab. This lab is unlike the previous two in that it will involve a combination of both code and answering questions on this paper. In particular, you are expected to complete the testing script test funcs.py and fix the errors in the module funcs.py (testing the module parse.py is optional). When you are done, show all of these (the handout, the test script, and the module) to your instructor. You instructor will then swipe your ID card to record your success. You do not need to submit the paper with your answers, and you do not need to submit the computer files anywhere. As with the previous lab, if you do not finish during the lab, you have until the beginning of lab next week to finish it. You should always do your best to finish during lab hours. Remember that labs are graded on effort, not correctness. 1. Using the cornelltest Module For the first part of the lab, you will do two things: learn about the module cornelltest, and use it in a script. Recall from class that a script is like a python module, in that it is a text file ending in the suffix.py. However, we do not import scripts. Instead we run them directly from the command line. Course authors: D. Gries, L. Lee, S. Marschner, W. White 1

For example, the file demo test.py for this lab is a script. To run this file, navigate the command line to the folder with this file (ask a consultant/instructor for help if you cannot figure out how to do this), but do not start Python (yet). When you are done, type the following: python demo test.py This will not give you the Python interactive shell with the symbol >>>. Instead, it will run the python statements in demo test.py and then immediately quit Python when done. You will notice that the script displays the help instructions for the module cornelltest. Page through this (the spacebar moves to the next page) and look at the functions available. Now open up the file demo test.py in Komodo Edit and comment out the first print statement (add a # at the beginning of that line). Add the followings lines, above the final print statement: cornelltest.assert equals('b c', 'ab cd'[1:4]) cornelltest.assert true(3 < 4) cornelltest.assert equals(3.0, 1.0+2.0) cornelltest.assert floats equal(6.3, 3.1+3.2) Do not indent these lines; they should have the same indentation as the print statements. Run the script from the command line. Because nothing was received that was not expected you will just get the output Done with demoing cornelltest, and nothing else. Now let us see what happens when something unexpected is received. In the first usage of assert equals, change 'ab cd'[1:4] to 'ab cd'[1:3]; then run the script again. This time, you should see answers to three important debugging questions: What was (supposedly) expected? What was received? Which line caused cornelltest.assert equals to fail? The last one is the most tricky. You may see more than one line number in the error message. We will talk about this later in class, but for now you only care about the first line number mentioned, the one in file demo test solution.py (the other line number is in a completely different file). What are the answers to three questions above? Now change the 3 back to a 4 on the first line so that there is no error. In addition, add this line before the final print statement (no indentation): cornelltest.assert equals(6.3, 3.1+3.2) Run the script one last time and look it what happens. Based on the result, explain when you should use cornelltest.assert floats equal instead of cornelltest.assert equals: 2

2. Create a Unit Test Script Now that you know how to use cornelltest, it is time to create a unit test script to check for any errors in the module funcs. We have started this unit test for you; it is the file test funcs.py. This file already has some code in it. In partiular, it has the line if name == ' main ': Recall from class that this prevents the the print statement underneath from executing should we (accidentally) import this script as a module. As a general rule, anything that is not a function definition or variable assignment should be indented underneath this line. Run the script, just like you did demo test.py. What happens? 2.1. The Class Point. We introduced the type Point in lecture; objects of type Point are points in 3-dimensional space. They have three attributes, x, y, and z, corresponding to the three spatial coordinates, stored as floats. You create Point objects with a constructor call, supplying three arguments to set the coordinates x, y, and z. For example, the constructor call Point(2,1,0) creates a Point object with (x,y,z) = (2.0, 1.0, 0.0) and returns the id of the object (what is written on the folder tab on the left). To use the class Point, you must import the module tuple3d. Therefore you have to preface the constructor call above with the prefix tuple3d, as you would for any function in the module. 2.2. Create a Test Procedure. The first function in the module funcs is has a zero(p). To test this, you are going to create a test procedure called test has a zero(). Right now, this procedure should just be a stub (e.g. it should not do anything at all). To make a stub procedure, just put pass indented under the header. So the procedure should look like this: def test has a zero(): pass A test procedure is not very useful if we do not call it. Add a call to the procedure in the script code (e.g. the code indented under if name...). Add the call before the print statement. That way, if anything goes wrong in the test procedure, the script will stop before printing out the final announcement. 2.3. Implement the First Test Case. In the body of function test has a zero(), delete pass and replace it with Python statements that do the following: Create a Point object (0,0,0) and save its name in a variable p. Remember that the constructor function Point(x,y,z) takes three arguments. Call the function has a zero(p), and put the answer in a variable result. Call the procedure cornelltest.assert equals(true,result). If you want, you can combine the last two steps into a nested function call like cornelltest.assert equals(true,has a zero(p)) 3

where p is a variable that contains the (name of) the point object. The procedure assert true will check if the value is True. If not, it will stop the program (before reaching the print statement) and notify you of the problem. Run the unit test script now. If you have done everything correctly, the script should reach the message 'Module funcs is working correctly.' If not, then you have actually made an error in the testing program. This can be frustrating, but it happens sometimes. One of the important challenges with debugging is understanding whether the error is in the code or the test. 2.4. Add More Test Cases for a Complete Test. Just because one test case worked does not mean that the function is correct. The function has a zero() can be true in more than one way. For example, it is true when x is 0, but none of the other coordinates are. Similarly it can be true when just y is 0, or when just z is zero. We also need to test points that have no zeroes in them. It is possible that the bug in has a zero() is that it returns True all the time. If it does not return False when the point has no zeroes, it is not working either. There are a lot of different points that we could test infinitely many. The goal is to pick test cases that are representative. Every possible input should be similar to, but not exactly the same as, one of the representative tests. For example, if we test one point with no zeroes, we are fairly confident that it works for all points with no zeroes. But testing (0,0,0) is not enough to test the other ways in which has a zero() could be true. How many representative test cases do you think that you need in order to make sure that the function is correct? Perhaps 6 or 7 or 8? Write down a list of test cases that you think will suffice to assure that the function is correct: 2.5. Test. Run the unit test script. If an error message appears (e.g. you do not get the final print statement), study the message and where the error occurred to determine what is wrong. While you will be given a line number, that is where the error was detected, not where it occured. The error is in has a zero(). 2.6. Fix and Repeat. You now have permission to fix the code in funcs.py. However, you should restrict your fixes to the function has a zero(p) only, as this is the only thing that you are testing. Do not fix the other function yet. Rerun the unit test. Repeat this process (fix, then run) until there are no more error messages. 3. Test the Procedure cycle left(p) The function cycle left() is actually a procedure. It does not return anything. Instead, this procedure changes the contents of the object (e.g. the folder) whose name is in p. Read the specifications of this procedure to understand what it does. 4

In module testfuncs.py, you should make up another test procedure, test cycle left(). Once again, this test procedure should start out as a stub; put pass under the header as you did with test has a zero(). You should also add a call to this test procedure in the script code, before the final print statement. 3.1. Implement the First Test Case. This procedure should take a point, and shift all of the coordinates to the left (with the x coordinate moving to the z coordinate). To test this out, you need to add the following code to test cycle left(). Create a Point object (0,0,1) and save its name in a variable p. Call the procedure cycle left(p). Test that p is now the point (0,1,0). The last step requires further details. You cannot write p == (0,1,0) This will return False. That is because (0,1,0) is not a Point object. It is a value of a type that we have not yet seen in class (and will not see for a while). Instead, you have to check each of the attributes x, y, and z separately. Remember that the attributes of p are all floats. Therefore, you want to use the function assert floats equal() to check that the values are all correct. So, to check that p is the point (0,1,0), you would add the following statements: cornelltest.assert floats equal(0,p.x) cornelltest.assert floats equal(1,p.y) cornelltest.assert floats equal(0,p.z) Add these test cases to the test procedure test cycle left() and run the unit test script. There should not be an error this time; check your test procedure if you run into any problems. 3.2. Add More Test Cases for a Complete Test. Obviously, the point (0,1,0) is not enough to test this function. We told you there was an error, and you have not found an error yet. Why is this point not sufficient to test the function shift? What are good points for testing out this function? Implement the test case(s) above, and run the script again. You should get an error message now. 3.3. Isolate the Error. Unit tests are great at finding whether or not an error exists. But they do not necessarily tell you where the error occurred. The procedure cycle left() has three lines of code. The error could have occurred at any one of them. 5

We often use print statements to help us isolate an error. Recall in class that something as simple as a spelling error can ruin a computation. That is why is always best to inspect a variable immediately after you have assigned a value to it. Open up funcs.py. Inside of cycle left, after the assignment to p.x, add the statement print p.x Do the same after the remaining two assignments (that is, print p.y and p.z). Now run the script. Before you see the error message, you should see three numbers print out. Those are the result of your print statements. These numbers help you visualize what is going on in cycle left(). There should be enough information that you can tell which value printed out is the one assigned to p.y. How do you tell this? 3.4. Fix and Test. You should now have enough information from these three print statements to see what the error is. What is it? Fix the error and test the procedure again by running the unit test script. 3.5. Clean up cycle left(). Unlike unit tests, using print statements to isolate an error is quite invasive. You do not want those print statements showing information on the screen every time you run the procedure. So once you are sure the program is running correctly, you should remove all of the print statements added for debugging. You can either comment them out (fine in small doses, as long as it does not make your code unreadable), or you can delete them entirely. However, once you remove these, it is important that you test the procedure one last time. You want to be sure that you did not delete the wrong line of code by accident. Run the unit test script one last time, and you are done. 4. The Function parse point() (OPTIONAL) This lab is now done; you do not need to do any more to get credit. However, we have provided another module to test, the module parse.py. The function within this module has a special type of error; one that you will likely run into on Assignment 1. Since the consultants are allowed to give you a lot more help on labs than assignments, it might be a good idea to try this part of the lab if you run into trouble. First, open the module parse.py and read the specification for the function parse point(). This function takes a string like '(1,2,3)' and turns it into the equivalent Point object. You should try to understand this function thoroughly, as it uses techniques found in the first assignment. As with the two previous problems, add a stub for a test procedure called test parse point(). In addition, put a call to this function in the script code. 6

4.1. Implement the First Test Case. Testing this function is very similar to testing cycle left(p). The primary difference is that parse point() is a function that returns a new Point, not a procedure that modifies an existing Point. So your test cases should be testing the point that parse(s) returns, not the string you pass to it. For example, your first test case should do the following: Call parse point('(1,2,3)') and assign the result to a variable p Test that p is now the point (1,2,3). Follow the steps from test cycle left() for the second step. 4.2. Oops. Something different happened. You did not get the nice AssertError message that you normally get from using cornelltest. Instead, you got a different error that looks like this. File "parse.py", line 45, in parse point p.y = float(ystring) ValueError: could not convert string to float: If you get something other than an AssertError, that means the Python crashed before it finished evaluating the function. So something inside of parse point() is causing it to crash. Unit testing is not going to help you find an error like this. Your program is crashing before it can evaluate assert floats equal() Furthermore, the line number in the error message is no help either. That is just where Python found the error; the mistake actually occurs much earlier in the function. Once again, you need to isolate the error with print statements. After every single assignment statement, add a print statement displaying the value of the variable from the assignment statement above. Run the unit test script and look at what is displayed on the screen. This should be enough information for you to find the error. The error here is a legitimate mistake that you might make in a function like this. We made it ourselves when we wrote this function, and then left it in for the lab. If you cannot find the error now, ask a consultant or instructor for help. 4.3. Fix and Test. Once you find the error, fix it. Run the test again, and fix it again if necessary. It is a good idea to leave the print statements in until you are sure that the function is correct. However, when it is correct, you should remove all of the print statements inside of parse point() (and test one last time!). 7