MCS-177 Project 2: Loops, Patterns and Accumulations, Oh My! (Spring 2015)

Start: Tuesday, 2/24; Due: Monday, 3/2, by the beginning of class


Overview

This project is designed to reinforce some of the concepts we have learned from lecture 3 - lecture 6. You should read the corresponding notes and Chapter 2 of your textbook before getting started.

This project has two tasks. For Task 1, you are going to write and evaluate for loops that will print out different number sequences. For Task 2, you are going to write functions with for loops, and set up accumulator patterns to add up the number sequences generated by the for loops.

You are to do this project individually.

Task 1

Start an IDLE session, the Python shell window should now appear. You are given five sequences of number below. For each of the sequences, you are to construct a for loop and use the print statement to print it out in the Python shell window. You should look up the lecture notes on how to set up a for loop (including the starting number, the stopping number, and the number increased in each iteration); how to utilize the loop counter; and how to use the print statement.
  1. 0 1
  2. 0
  3. 3 4 5 6
  4. 5 9 13 17
  5. 8 7 6 5 4 3

We have provided for you a template file. After you have finished writing and evaluating your for loops, please cut and paste them along with the sequences of number printed (your input and output) underneath the corresponding questions (Task 1, questions 1 - 5) in the template.

Task 2

We call this task "twelve days of Christmas"; consider the following traditional Christmas song:

On the first day of Christmas
My true love gave to me
A partridge in a pear tree.

On the second day of Christmas
My true love gave to me
Two turtle doves
And a partridge in a pear tree.

On the third day of Christmas
My true love gave to me
Three French hens,
Two turtle doves,
And a partridge in a pear tree.

And so on, through the twelfth day of Christmas. Let's count a partridge in a pear tree as constituting a single present, so that on the first day, my true love gave me one present. Similarly on the second day my true love gave me three presents, on the third day six presents, and so on.

If I wanted to figure out how many presents I received on a particular day, the most straightforward approach would be to add them all up. Section 1.4 in our textbook explains a slicker approach based on visualizing the presents that day as arranged in a triangle. The triangle can fit together with another equal-sized triangle to form a rectangle. This allows a direct calculation of the number of presents on day n as n(n+1)/2. If all is well, both approaches ought to give the same answers.

Suppose we instead want to figure out my total haul for the entire Christmas season. Added up over all twelve days, how many presents did my true love give me? The geometric approach still works, if you can visualize three-dimensional shapes well enough. You can lay down the big triangle from day 12, stack on top of it a smaller triangle from day 11, and so forth on up to form a pyramid. If you figure out how many of those pyramids fit together to form a rectangular solid, and how long each of the three sides of the rectangular solid are, you can derive a formula for the total number of presents. But I don't recommend you try this, at least without having a more straightforward calculation to check your work against, because most humans aren't very good at rotating pyramids around in their heads. So let's write a straightforward program that totals up the answer. While we're at it, we can compare the two approaches in the single-day case as well.

Here is what you need to do for this task:

  1. Open up a new file window in IDLE and type in a definition for a function, presentsOnDay. The function should have one parameter, specifying which day of Christmas you are interested in. (For example, you would pass in 12 to find out how many presents my true love gave me on the 12th day of Christmas.) Be sure to use a descriptive name for the parameter. Your function should return the overall number of presents for the specified day. Use the accumulator pattern to calculate the answer by adding up all the different kinds of presents. Save your program in a file called xmas.py.

  2. Use IDLE's "Run Module" command from the Run menu, or equivalently press the F5 key. If IDLE reports any syntax errors in your program, fix them. When you get past that hurdle, use the Python shell window of IDLE to try your presentsOnDay function out for days 1, 2, and 3. Make sure your function gives the same answers as the ones previously mentioned; if not, fix it. Once you are confident that the function is working, find out how many presents are on day 12 (write it down).

  3. Add a second function in the same file, this one called presentsThroughDay. It should again have a single parameter, this time indicating the last day number you are interested in. For example, if you passed in the number 12, it would indicate that you were interested in all days up to and including day 12. The function should return the total number of presents, added up across all the days. You should again use the accumulator pattern to do this. Each time your function needs to find the number of presents on a particular day, it should use presentsOnDay.

  4. Make sure your presentsThroughDay function produces the right answers if you ask it about just the first day, or the first two days, or the first three days. Fix any errors you discover. Then find out the total number of presents my true love gave me over the full 12-day Christmas season (write it down).

  5. One question about an algorithm is whether it produces the correct result. But another question is how well it scales up to larger problem sizes. My true love actually is generous enough to give me presents even outside the Christmas season. Get a sense for how well the straightforward algorithm using two accumulations can accommodate this by trying presentsThroughDay out with values such as 10, 100, and 1000. (For example, my parents have been married for over 12775 days.) How far do you have the patience to go? If a computation is taking too long, you can stop it using the control-c key combination.

  6. In the xmas.py file window, select your presentsOnDay function definition by dragging the mouse through it. Then use the "Comment Out Region" command from the Format menu, or equivalently the control-3 key combination. This should put ## characters at the beginning of each line. In Python, anything from a # character to the end of the line is a "comment," that is, not an actual part of the program that will get run. So effectively you have removed this function definition by turning it into nothing but comments. The advantage is that it is still visible and can be uncommented if you ever want it back. Now add the following definition to the file:

        def presentsOnDay(day):
            return day*(day+1)//2
    

    Now if you go back to trying presentsThroughDay with large numbers of days, you should find that it scales up much better but still gives the same answers . With the new version, how large a number of days do you have patience for?

  7. Finally, in the template file we have provided for you, write down the following under the corresponding question (Task 2, questions 7):

Submitting your work

You will be submitting your code using Moodle; click on the following link for instructions on submitting code using Moodle. For this project, you will need to submit the following 3 files (with the following recommended names):

Grading

You will earn one point for each of the following accomplishments:

  1. You wrote a for loop that provided the correct output for Task 1 question 1.

  2. You wrote a for loop that provided the correct output for Task 1 question 2.

  3. You wrote a for loop that provided the correct output for Task 1 question 3.

  4. You wrote a for loop that provided the correct output for Task 1 question 4.

  5. You wrote a for loop that provided the correct output for Task 1 question 5.

  6. You have written a correct contract and docstring for the presentsOnDay function.

  7. Your presentsOnDay function uses the accumulator pattern to calculate its answer.

  8. Your presentsOnDay function returns an answer. Your presentsOnDay function calculates the correct answer.

  9. (Under Task 2, questions 7 in the template) You stated the number of presents for day 12.

  10. You have written a correct contract and docstring for the presentsThroughDay function.

  11. Your presentsThroughDay function uses the accumulator pattern to calculate its answer.

  12. Your presentsThroughDay function uses the presentsOnDay function.

  13. Your presentsThroughDay function returns an answer. Your presentsThroughDay function calculates the correct answer.

  14. (Under Task 2, questions 7 in the template) You stated the total number of presents through day 12.

  15. All variable and parameter names in your functions are descriptive.

  16. (Under Task 2, questions 7 in the template) Your paragraph explains what function has two different versions. Your paragraph reports on whether the two algorithms computed the same answers in the cases where you tested both.

  17. (Under Task 2, questions 7 in the template) Your paragraph makes it clear whether you compared the two versions directly, or in the context of their use by some other function. (In the latter case, you make clear which other function.)

  18. (Under Task 2, questions 7 in the template) Your paragraph indicates in a general way how the speeds compared. For example, you might say "I didn't notice any difference for parameter values up to ..., but by the time I got to ..., ... was taking several seconds whereas ....."

  19. (Under Task 2, questions 7 in the template) Your paragraph gives the largest value you were willing to wait for with the slow algorithm and approximately how long it took. (Seconds? Minutes? Tens of minutes?)

  20. (Under Task 2, questions 7 in the template) Your paragraph gives the largest value you were willing to wait for with the fast algorithm and approximately how long it took. (Seconds? Minutes? Tens of minutes?)