Com S 127x - Lab 6 1. READING FLOWCHARTS WITH CONDITIONAL ACTIONS! The U.S. Postal Service has some complex rules for deciding how much it costs to mail a letter. We ll use a small part of these rules as an example of writing conditional statements. The rule is as follows: Rule 1: For an ordinary letter up to 3.5 ounces, the cost is.49 for the first ounce plus.22 for each additional ounce (or part of an ounce). Try some examples: A letter that is 1 ounce (or less) is just.49. For a 2.3 ounce letter, the cost is.49 + 2 *.22 =.93(.49 for the first ounce and for the remaining 1.3 ounce it is 2 *.22) For a 3 ounce letter the cost is also.49 + 2 *.22 =.93 For a 3.1 ounce letter the cost is.49 + 3 *.22 = 1.15 The process above could be described in pseudocode something like this: if the weight is less than or equal to 1.0 cost is.49 else subtract 1 from the weight, round up to the next whole number, and multiply by.22 add the result to.49 To translate this into Python code, we need to be able to take a float value and round "up" to the next whole number. Fortunately there is a function in the math module, called ceil() (short for ceiling ) that does exactly what we want. Try this: >>> import math >>> math.ceil(2.3) 3.0 >>> math.ceil(3.0) 3.0 >>> math.ceil(3.1) 4.0 So here is an example of a Python function that returns the postage for a given weight up to 3.5 ounces. (To try this in a script, remember to import the math module.) def postage(weight): if weight <= 1.0: else: + math.ceil(weight - 1) *.22
Now, to make things more interesting, let's add the rule for letters over 3.5 ounces: Rule 2: For letters over 3.5 ounces, the cost is.98 for the first ounce plus.22 for each additional ounce (or part of an ounce). For example, a 3.5 ounce letter would cost.49 + (3 *.22) = 1.15 [From rule 1] a 3.8 ounce letter would cost.98 + (3 *.22) = 1.64 [From rule 2] a 10 ounce letter would cost.98 + (9 *.22) = 2.96 [From rule 2] Now to calculate the charges for letter of any weight, you will have to make use of both the rules and calculate the charges. Notice you have to check the actual weight to see if it is bigger than 3.5, but then round up when you compute the extra ounces. Let us try to capture the above rules in a flowchart. Figures 1, 2, and 3 are flowcharts representing different attempts to program the rules above. They are not necessarily correct! Exercise 1 Trace through each flowchart by hand using some sample values as in the examples above. Decide which flowcharts are correct and which are incorrect. For each one that is incorrect, give a specific example in which the wrong answer is produced. Show the TA what you concluded. WRITING CONDITIONAL STATEMENTS; USING A UNIT TEST Now, for each flowchart, write a Python function that implements it. The function should be named postage and should have one parameter representing the weight. The function should return the postal charge calculated. Put the three functions in three separate files called postage1.py, postage2.py, and postage3.py. To test your functions, download the module postage_test.py from http://web.cs.iastate.edu/~adisak/cs127x/lab6/postage_test.py This is an example of a unit test.
WHAT IS A UNIT TEST It is just a short script that calls the postage() function multiple times with different values, so you can check the results. To make it easier to check the results, the expected (correct) result is printed after function is called. You can choose which version of the function is being tested by editing the import statement at the top. Verify that the results agree with your conclusions from reading the flowcharts. (Remember, agreeing with the flowchart does not necessarily mean it gives correct answers!) Reminders: 1. Your modules need to be in the same directory as the postage_test script in order to be imported. 2. Remember that Python uses indentation to determine which statements are grouped together, so watch the indentation levels carefully. For example, here is yet another version of a postagecalculating function (one that does not match any of the flowcharts) that has another conditional statement nested inside the else statement block: def postage(weight): if weight > 3.5: cost =.98 + math.ceil(weight - 1) *.22 else: if weight > 1: cost = cost + math.ceil(weight - 1) *.22 Indentation level for inner if block Indentation level for outer if and else blocks Indentation level for function body Exercise 2 Show the TA your three modules and the results of running the unit test on each version. Note that when you start testing you might see values like: 0.93000000000000003 for the postage on a 3 ounce letter. Why do we get that weird-looking number instead of just.93
Well, floating-point arithmetic is never exact, so we are seeing the natural result of rounding errors. All we can do here is mentally round the result to the nearest cent. (An alternative would be to do all calculations in pennies using integer arithmetic.) Start weight <= 1 weight <= 3.5 + ceil(weight 1) *.22 cost =.98 + ceil(weight 1) *.22 Figure 1
Start weight <= 1 weight > 1 + ceil(weight 1) *.22 weight > 3.5 cost =.98 + ceil(weight 1) *.22 + ceil(weight 1) *.22 Figure 2
Start cost = cost + ceil(weight 1) *.22 weight > 1 cost = cost +.49 weight > 3.5 Figure 3 CREATING A FLOWCHART FROM A PROBLEM STATEMENT Now we are going to construct a flowchart for a problem. The problem statement is as follows: Normally, labor laws require that employees who are paid an hourly wage have to be paid extra whenever they work more than 40 hours per week. The extra is usually 1½ times the regular hourly wage for all hours above 40. However, an exception is made for employees with exempt status, which is meant for positions such as managers and supervisors. They don t get paid any extra for overtime.
Work out the examples below using a pencil and paper, and make sure you get the results shown: 1. 20 hours, rate $10.00 per hour, non-exempt : total wages $200 2. 20 hours, rate $10.00 per hour, exempt : total wages $200 3. 44 hours, rate $10.00 per hour, non-exempt : total wages $460 4. 44 hours, rate $10.00 per hour, exempt : total wages $440 Next, sketch a flowchart representing the calculation. Assume that you have three variables, the hours, the hourly rate, and the status (assume the status is either the string exempt or the string non-exempt ). Finally, implement a Python function that has three parameters (again the hours, the hourly rate, and the status) that prints the total wages. Also write a short unit test for it similar to postage_test.py, based on the four sample calculations above. You should print what arguments are being tested, the expected result, and then the result you get from actually calling the function. Exercise 3 Show your flowchart and demonstrate your Python function to the TA.