Sie sind auf Seite 1von 6

1

Laboratory #2, Test-Driven Development


Extension Class, March 2019
Ing. Eléctrica. Universidad Tecnológica de Pereira
Handout written by Germán A. Holguín L.

Abstract—In this lab you will practice with simple while loops, and at the same time you will use formal software development methods
such TDD to solve problems. Input/Output redirection is introduced as a method for automatic testing on functions that include
standard input.

Index Terms—Python, Loops, Flowcharts, Test Cases.

1 S TARTING UP. 5) Write Python code such


• This lab is STRICTLY individual. Every student has a) implements your proposed flowchart, and
to type, work, solve, and submit this lab individually. b) pass ALL test cases.
• Answers to questions in this lab, should be written
as comments in the respective section of your code. 6) Write a separate file that uses your function and
• Do not forget the ’docstring’ of every single Python name it lab2_user_PX.py where X is the problem
file you create. It must contain at least a description number.
of the file, names and affiliation of authors. • You will need an import statement in your
DO NOT LEAVE until your work has been checked up by new user file.
your TA or instructor, AND until your google classroom Problems P1 and P2 are tutorials. They are solved step
submission has been verified. by step. You just need to follow, understand, and re-
implement by yourself the given solution.
Problem P3 however, is for you to solve using the same
2 C REATE A PROJECT FOR L AB 2.
methodology you just learned. Some tips are going to be
Create a new PyCharm project. Name it Lab2. provided.

3 P ROBLEMS . 3.1 Problem P1. (P3.39 from [1])


For each of the following problems, you are required to: When you use an ATM with your bank card, you need to
provide a Personal Identification Number (PIN). If a user
1) Read and understand the problem statement and
fails to provide the correct PIN more than two times, the
the task.
ATM will block the card. Write a program that ask the user
• Describe Inputs, Outputs, and type of vari- for the PIN no more than three times, and accepts or rejects
able and semantics for each of them. the PIN number.
• Describe ALL possible test cases you can
• Assume the correct PIN number is 1234
think of.
• Use stdin to prompt for the PIN number
2) Create a Python script and name it as lab2_PX.py • Use stdout to report:
where X is the problem number.
– "Your PIN is correct"
3) Write a template for your function and layout ALL
– "Your PIN is incorrect. Try again"
your test cases.
– "Your card has been blocked. Call your bank"
a) This is, you first write a function prototype,
defining inputs and outputs, and then 3.1.1 Step 1. Problem Understanding.
b) write a function prototype to run all test • Program ask the user for the PIN number.
cases. • Maximum number of tries is 3. Generalize it.
4) Draw a flow chart for your proposed solution. – If the user provides an incorrect PIN at the
third opportunity, block the card.
• Use any software to draw this flow chart. One
– This is equivalent to say: maximum 2 fails, or
recommendation is flowgorithm.
maximum 3 tries.
• You must name this picture
lab2_flowchart_PX.jpg where X is • We need a function that ask for PIN certain number
the problem number. of tries, and returns a Boolean:
2

– True if the PIN is correct. Algorithm 1 Template for Lab2_P1.py


– False if is not.
1 """
2 Program to validate PIN number of an ATM customer.
• Inputs: 3 """
4
– Maximun number of tries. Integer. 5 def validatepin(maxtries):
– PIN number. Integer. 6 pass # your code goes here
7 return accepted
• Output: 8
9 def testreport(testnumber, testresult):
– PIN is valid. Boolean. 10 """
11 Function to print the result of a test case
12 :param testnumber: An integer with test ID number.
• We need test cases for at least: 13 :param testresult: A boolean with the result of
current test.
– Correct PIN at first try. 14 :return: nothing.
– Correct PIN at second try. 15 """
16 if testresult:
– Correct PIN at third try. 17 print("Test %d has passed." % testnumber)
– No correct PIN. 18 else:
19 print("Test %d has FAILED !!!! <<<< WARNING" %
Your are welcome to include more test cases as you see fit. testnumber)
20
21 if __name__ == "__main__":
3.1.2 Step 2. Python Script 22 # In this example we assume maximum tries is 3.
23 # You might want to add test cases that consider
Create a new python file and call it Lab2_P1.py. 24 # differents values other than 3.
25 MAXTRIES = 3
3.1.3 Step 3. Template and Test cases. 26
27 # Test case 1:
In this case, let us implement a function called 28 # correct PIN at first try:
validatepin(). 29 test1 = validatepin(MAXTRIES)
30
31 # Test case 2:
• Inputs: Although the problem says the maximum 32 # correct PIN at second try:
number of tries is 3, we can generalize this problem 33 test2 = validatepin(MAXTRIES)
to N tries. This general value can be an argument in 34
35 # Test case 3:
your function. Let us call that argument maxtries. 36 # correct PIN at third try:
• Outputs: The function should let us know if the PIN 37 test3 = validatepin(MAXTRIES)
38
was accepted or not. So, the function must return a 39 # Test case 4:
Boolean variable called accepted. 40 # No correct PIN:
41 test4 = not validatepin(MAXTRIES)
Algorithm 1 shows a prototype (a function definition with- 42
43 testreport(1, test1)
out the actual implementation - just holding the keyword 44 testreport(2, test2)
pass). 45 testreport(3, test3)
46 testreport(4, test4)
• There is one more file to create this time.
• In order to avoid typing all inputs yourself every
time you run your program, let us put all of them
in a new plain text file.
• Each input should be in a different line.
• You can use PyCharm to create plain text files. Just
right click on your project and select New >> File,
(not Python File) as in figure 1.

Figure 2. inputs_testcases_P1.txt
Figure 1. New plain text file in PyCharm.
Examine this file, and make sure you understand why
• Name your new file as each of this numbers are in their current positions. Here a
inputs_testcases_P1.txt. ( Notice the txt short explanation for this case:
extension, NOT py). • On test1 your input needs to be the correct PIN in
• Then, inside your new plain text file, write down the the first try. This is line 1 in figure 2.
inputs for all your test cases in the same order, one • On test2 your input needs to be an incorrect PIN first
line per input. In this case, for example, the new file and then the correct one. These are lines 2 and 3 in
will look as shown in figure 2. figure 2.
3

• On test3 your input needs to be two incorrect PINs If you attempt to run this python script from the Py-
followed by the correct one. These are lines 4 to 6 in Charm run utility, you will have to type input values in the
figure 2. PyCharm run console.
• On test4 your input needs to be three incorrect PINs. However, the main idea in creating a input file is to avoid
These are lines 7 to 9 in figure 2. typing anything during the test. This can be done by stdin
redirection. In a command line, you can use operator < to
Since the test cases were layout in this particular order, this
redirect the stdin or > to redirect the stdout.
input file should follow that order too.
To run this program:
3.1.4 Step 4. Flowchart proposal 1) Open the PyCharm Terminal.
Figure 3 shows a proposal. Remember this is the design part CAREFUL: Do not confuse Terminal with Python
of the problem. Here you are thinking what should be the Console. A Terminal is an OS command prompt.
behavior of your algorithm. In general, every person will The PyCharm Terminal has the advantage of be-
create a slightly different solution. ing inside the PyCharm GUI. Remember, command
dir will show you the content of the current folder.
2) In the Terminal, execute your program with this
pinvalidw command:
(Integer maxtries)

$ python Lab2_P1.py < inputs_testcases_P1.txt


tries = 0

accepted = False
What this command is telling the OS is: Using python
as interpreter, execute script Lab2_P1.py and send the
True
tries < maxtries and not
accepted
content of file input_testcases_P1.txt to stdin.
False
Input pin
3.1.6 Step 6. Using your function in some other python
False True
script
pin ==
CORRECTPIN
If you ever need your new function somewhere else, just
import it using any of the import method you know.
tries = tries + 1 accepted = True

False True
Output "Your PIN is Correct" Algorithm 3 Function called from another program.
tries ==
maxtries

1 """
Output "Your PIN is Output "Your Card has been 2 Program that uses a function to validate
incorrect, Try again" blocked. Call your Bank"
3 a PIN in an ATM.
4 """
5
6 from Lab2_P1 import validatepin
7
Return Boolean accepted
8 accepted = validatepin(3)

Figure 3. Flowchart proposal using a while loop 3.2 Problem P2.


Let’s write a program that computes the average of all your
3.1.5 Step 5. Python Implementation. grades for a given course. Grades are numbers between 0
A python implementation for the flowchart we draw in step and 100. Use −1 as a sentinel value to end the program.
4.
A sentinel value, is a value that is clearly out of the range
Algorithm 2 Function validatepin() in a particular problem, and therefore this number can be
used to stop a while loop. In this case −1, or any negative
1 def validatepin(maxtries): number for that matter, can be used as sentinel value since
2 CORRECTPIN = "1234"
3 tries = 0 course grades are usually non-negative.
4 accepted = False
5 while tries < maxtries and not accepted: 3.2.1 Step 1. Problem Understanding.
6 pin = input("Please, enter your PIN: ")
7 if pin == CORRECTPIN: • What this means is, you don’t know beforehand how
8 accepted = True many grades the user is going to type.
9 print("Your PIN is Correct")
10 else: – You need to prompt the user for numbers until
11 tries += 1 # tries = tries + 1
the user enters −1.
12 if tries == maxtries:
13 print("Your card has been blocked – This is a while loop. The clue was "until".
. Call your bank")
14 else: • You need to keep a record of how many scores have
15 print("Your PIN is incorrect, Try been entered, and the total sum of them.
again")
16 return accepted – So, we need two variables to store those val-
ues.
4

• The result is the total sum divided by the number of Algorithm 4 Template for Lab2_P2.py
grades.
1 """
2 Program to compute average over an undetermined
– What if the first input is −1? 3 number of grades in the range 0 to 100.
– A division by zero must be prevented. 4 """
5
6 def gradesaverage():
• We need to write a function such: 7 """
8 Function to solve the given problem.
– Function arguments: None 9 :return: final. A float.
10 """
– Function return: The final average grade. 11 pass # your code goes here
12 return final
• Test cases must include different input sizes and 13
14 def testreport(testnumber, testresult):
values. 15 """
16 Function to print the result of a test case
– Testing for (−1) as the first input is a must. 17 :param testnumber: An integer with test ID number.
18 :param testresult: A boolean with the result of
current test.
3.2.2 Step 2. Program Script. 19 :return: nothing.
20 """
Create a new python file and call it Lab2_P2.py. 21 if testresult:
22 print("Test %d has passed." % testnumber)
23 else:
24 print("Test %d has FAILED !!!! <<<< WARNING" %
3.2.3 Step 3. Write a template for your problem solution. testnumber)
25
We need a function for computing the grade average. This 26 def comparefloats(first, second):
function takes no inputs and returns the final grade average. 27 """
28 A function to compare two floats.
Here is a minimal set of test cases. You can add as much 29 :param first: One float number to compare.
as you see fit: 30 :param second: The other float number.
31 :Return: A Boolean. True if inputs are within
tolerance.
1) The first input is −1. Result should be zero. 32 """
2) One grade. 10. Result should be 10. 33 # define your tolerance
34 TOL = 1E-14
3) Two grades. 10 and 20. Result should be 15. 35 # return
4) Three grades. 10, 20, and 30. Result should be 20. 36 return abs(second - first) < TOL
37
5) Four grades. 50.5, 60.5, 70.5, 80.5. Result should be 38 if __name__ == "__main__":
65.5 39 # Test cases:
40
41 # Test 1: The first input is -1. Result should be
Remember, to compare float numbers just test if they are zero.
within a tolerance (example: 10−14 ). Do not compare floats 42 test1 = comparefloats(0, gradesaverage())
with ==. 43 # Test 2: One grade. 10. Result should be 10.
44 test2 = comparefloats(10, gradesaverage())
45 # Test 3: Two grades. 10 and 20. Result should be
• There is one more file to create this time. 15.
• In order to avoid typing all inputs yourself, lets put 46 test3 = comparefloats(15, gradesaverage())
47 # Test 4: Three grades. 10, 20, and 30. Result
all of them in a new plain text file. should be 20.
• Each input should be in a different line. 48 test4 = comparefloats(20, gradesaverage())
49 # Test 5: Four grades. 50.5, 60.5, 70.5, 80.5.
• You learned how to create plain text files in Lab1. Result should be 65.5
However, this time you can use PyCharm to create 50 test5 = comparefloats(65.5, gradesaverage())
51
it. Just right click on your project and select New >> 52 # Test reports
File, as in figure 4. 53 testreport(1, test1)
54 testreport(2, test2)
55 testreport(3, test3)
56 testreport(4, test4)
57 testreport(5, test5)

Figure 4. New plain text file in PyCharm.

• Name your new file as


inputs_testcases_P2.txt.
• Then, inside your new file, type the inputs for all
your test cases in order, one line per input. In this
case, for example, the new file will look as shown in
figure 5.
5

Examine this file, and make sure you understand why Algorithm 5 Python code for the problem P2.
each of this numbers are in their current positions.
1 def gradesaverage():
2 """
3.2.4 Step 4. Design a flowchart for your solution. 3 Function to compute average of grades.
4 :return: Final: The average.
Every single person will have a slightly different solution, 5 """
6
although in general they might do the same. Here is a 7 # initialize variables.
proposal. 8 sum = 0
9 counter = 0
10 done = False
11

gradeaverage
12 # Loop until is sentinel value is entered
13 while not done:
14 grade = float(input("Enter a grade: "))
sum = 0 15
16 # this next two lines are only for testing
purposes.
counter = 0 17 # when running in __main__ with input
redirection
18 # from a file, you want to see the input. So,
done = False
print it.
19 if __name__ == ’__main__’:
True 20 print(grade)
not done 21

False 22 # do we get the sentinel value yet?


Input grade
23 if grade < 0:
24 done = True
False True
25 else:
grade < 0 26 # otherwise, accumulate grade.
27 sum = sum + grade
28 # increment counter
sum = sum + grade done = True 29 counter = counter + 1
30
31 # If we got at least one grade:
counter = counter + 1
32 if counter > 0:
33 # compute
34 final = sum / counter
35 else:
36 # if no grades, output is zero
37 final = 0
False True 38 # return final
counter > 0
39 return final

final = 0 final = sum / counter

2) In the Terminal, execute your program with this


command:
Output final

$ python Lab2_P2.py < inputs_testcases_P2.txt


Return Real final
What this command is telling the OS is: Using python
as interpreter, execute script Lab2_P2.py and send content
of file input_testcases_P2.txt to stdin.
Figure 6. P2 Flowchart Proposal.

3.2.6 Step 6. Using your function in some other python


3.2.5 Step 5. Write a function that solves your problem and script.
passes all test cases.
If you need your new function somewhere else, just import
In this case, we will implement the flowchart we draw in it using any of the import method you know.
step 4, as shown in Algorithm 5.
If you attempt to run this python script from the Py- Algorithm 6 Function called from another program.
Charm run utility, you will have to type input values in the
PyCharm run console. 1 """
2 Program that uses the grades average function.
However, the main idea in creating a input file is to
3 """
avoid typing anything during the test. This can be done by 4
stdin redirection. In an OS command prompt, you can use 5 from Lab2_P2 import gradesaverage
operator < to redirect the stdin or > to redirect the stdout. 6
7 myaverage = gradeaverage()
To run this program:
1) Open the PyCharm Terminal.
CAREFUL: Do not confuse Terminal with Python 3.3 Problem P3.
Console. A Terminal is an OS command prompt.
The PyCharm Terminal has the advantage of be- Problem Statement
ing inside the PyCharm GUI. Remember, command A weather station is continuously transmitting tempera-
dir will show you the content of the current folder. ture values in the Celsius scale. When the communication
6

channel opens it can transmit hundreds or even thousands


of temperature values, one at a time. When no more data
is available, the weather station sends an "END". Your
customer wants to have a report on a file with time and
date when each of those values arrived, the original value
in Celsius and it correspondent equivalent in the Fahrenheit
scale.

Tips
1) Assume that the weather station is connected to
your standard input.
2) For every input, your program should produce stan-
dard output of the form:
Tue Feb 20 13:35:26 2018, Temperature
is 17.9000 C = 64.2200 F
• (use %10.4f for the temperature values)
3) The current date and time can be obtained using the
function ctime() from the module time.
from time import ctime
4) A file with all output can be created using redirec-
tion of stdout in Terminal.
python Lab2_P3.py < inputs_P3.txt >
output_P3.txt
5) Your program can be tested with some 3 or 4 short
cases.
If the time is obtained from the computer then it will
be different every time you run a test. How do you
test for it then if a comparison with a fixed value
will always fail?
6) In Step 6, use your program to convert all values
from −200.0 C up to +200.0 C in steps of 0.1 C.
Tip: Those are 4000 values. You don’t want to type
them manually into a file. But you can write a very
short python program (5 python lines) that writes
them for you.

4 F INISHING UP.
For this lab you have created several files.
1) Create a ZIP file (only one zip file called Lab2.zip)
containing all files you have created.
These include all .py files, .txt files and all
flowcharts you have created.
2) Upload it to Laboratory #2 assignment in Google
Classroom.
• This is an individual lab.
3) Before leaving the lab, verify with your TA/In-
structor that the submission was correct.

R EFERENCES
[1] Cay S. Horstmann and Rance D. Necaise. 2015. Python for Everyone
(2nd ed.). Wiley Publishing.

Das könnte Ihnen auch gefallen