CS1101:Assignment 1

Writing simple functions and programs

Assigned: Tuesday, August 28
Due: Thursday, September 6 at 11 PM

For this assignment you will write two programs: one uses integer arithmetic to compute the day of the week for any given date.  The other uses floating-point arithmetic to compute the area of a triangle, given the lengths of its sides or the coordinates of its vertices. In both cases I will describe the algorithm completely: it is your job to translate these descriptions into working Python programs.

It is important to write good modular code: in each of the two programs, the actual computation will be carried out by a function that you write, which itself does not read any keyboard input or write any output to the screen.  The main program will handle the user input and output and call the appropriate functions.

You should use as a the windchill program posted on the course website as a model; the programs that you write will have the same basic structure.



1. What Day Were You Born?

No, I don't mean what your birthday is. What day of the week were you born?  I was born on Tuesday.  Computing the day of the week from the date is a fairly elaborate calculation, in part because of the complicated rule for when a year is a leap year.  (If you think the rule is just:  "If the year is divisible by four, it's a leap year,"  then you haven't got the whole story!)

You will write a program that prompts the user to type in the month, day and year of a date.  For instance, if the date is January 15, 2015, the user will be prompted for the month and type 1, then for the day of the month and type 15, and then for the year and type 2015.  The program responds with an answer 0 through 6, where 0 denotes Sunday, 1 Monday, 2 Tuesday, etc.  Having the answer come out in this form is not very satisfying. A simple enhancement, suggested in the final step below, will solve this problem.

Step 1. The Algorithm. Here is an algorithm for solving this problem.  Integer arithmetic is used throughout,  so 'divide' means 'divide and throw away the remainder', and the operation appears in Python code as //.  Incidentally, this is an adaptation of something called Zeller's Algorithm, which I found on Wikipedia.  It is not the simplest algorithm for computing the day of the week from the date, but it doesn't require the use of tables or of conditional instructions (as in, 'if the year is less than 1865 then go to step 9, otherwise go to step 11') so it is possible to code it using just what you've learned at this stage.

  1. Add 9 to the month, take the remainder upon division by 12, and add 4.  This is the adjusted month.  (As a result, the adjusted month is 4 for March, 5 for April, ...,  13 for December, 14 for January, and 15 for February.)
  2. Subtract the adjusted month divided by 14 from the year.  This is the adjusted year.  (The effect is to subtract 1 from the year if it's January or February.)
  3. Take the adjusted year divided by 100.  This is the century.  (The century is the first two digits of the year.)
  4. Take the remainder that the adjusted year leaves upon division by 100.  This is the century year.  (The century year is the last two digits of the year.)
  5. Multiply the adjusted month by 26, and divide by 10. This is the month correction. (I can't explain this step; it's just... magic.)
  6. Add the following values:  The day, the month correction, the century year, the century year divided by 4, the century divided by 4, and 5 times the century.
  7. Add 6 to the result in step 6, take the remainder upon division by 7.  This is the day of the week, with 0 denoting Sunday, 1 Monday, etc.

For example if we use today's date, August 28, 2018, we get the following calculation:

1. adjusted month = (8+9)%12+4 = 5 + 4 = 9.
2. adjusted year = 2018-9/14 = 2018-0=2018.
3. century = 2018/100 = 20.
4. century year = 2018%100 = 18.
5. month correction = (26 x 9)/10 = 234/10 = 23.
6. Add: 28 + 23 + 18 + 18/4 + 20/4 +5x20=28+23+18+4+5+100=178. 
7. (178+6)%7 = 184%7 = 2, which stands for Tuesday.  Which is right!

Make sure that you can execute this algorithm by hand before proceeding.  Your job is to encode it in  Python.  Much of the work has already been done in the recipe above, by identifying the critical variables.

Step 2. Write the calendar function.  (25 points) Download the file calendar.py and save it in your folder.  Put your own name in a comment at the start of the file. The heart of the program is the function day_of_week.  The header of this function has already been provided for you.  Currently the function has a dummy return value of 0, but you should get rid of this line and replace it by the code implementing the algorithm described in Step 1.  When you have finished, you can test it by selecting the Run Module option from the Run menu in IDLE, and then typing

day_of_week(8,28,2018)

You should get the answer 2, as in the calculation above.  Try this out with other dates for which you know the day of the week and make sure you get the correct answer.  Try it with your date of birth.

Step 3.  Write the main program section. (20 points) This will simply prompt the user for the three inputs and print the output.  So, for example, a typical session with the program would be:

Enter the month: 8
Enter the day of the month: 28
Enter the year: 2018
Day of week: 2


Step 4.  Nicer output. (5 points) Here is an enhancement that you can try.  Instead of printing an answer like 2, wouldn't it be nicer if the program actually printed Tuesday ? Later we will introduce Python statements that say, in effect,  'if the result is 0, print Sunday, otherwise if the result is 1, print Monday, etc.'  But it is possible to solve this problem using only the stuff we have learned so far in class, using string slices and a little trick. See if you can figure it out.  (HINT:

Sunday   Monday   Tuesday  WednesdayThursday...
)


Again, test your program thoroughly with dates whose corresponding days of the week you know.

2. The Area of a Triangle

In the simpler version of the problem, you will write  a program that prompts the user to enter the lengths of three sides of a triangle and then prints the area of the triangle. In the more complex version, the user will be prompted to enter  the x- and y-coordinates of three vertices of a triangle instead of the lengths of the sides.  If you do the more complicated version, you do not have to submit a solution for the simpler one.

Whichever version you choose, the prompt strings themselves should be clear enough so that the user of the program knows which value to enter at each prompt.  The output as well should include a clear message.

Step 1. The algorithm:  Specifying the lengths of the three sides of a triangle completely determines the three angles of the triangle, and thus the area.  So there ought to be a way to compute the area of the triangle just from the lengths of the sides.  The formula you probably learned in school for the area of a triangle (half the base times the height) does not tell you in any direct way how to do this, but there is another formula, much less well known, that does the trick.  The area of the triangle whose sides have lengths a, b, and c is



where s is half the perimeter of the triangle; that is,



Step 2.  The area function. (25 points) Download the file triangle.py.  Put your own name in the comment section and supply the code for the function area, using the algorithm described above.  Test it by choosing the Run Module option in IDLE and typing

area(3,4,5)

at the prompt.  This should give the area of a right triangle with base 3 and height 4, which is 6. Test this with other triangles for which you know the area.  Try it with side lengths 1,1,2 and then with side lengths 1,1,3.  What do the results mean?

Step 3. The distance function.  (10 points) If you want, you can now write the simpler version of the main program, which just asks the user for the three side lengths.  But if you go farther, you should start to  implement the version in which the main program asks the user for the coordinates of the vertices.  Before you can do this, you need to compute the lengths of the sides from these coordinates.
You might recall that the distance between two points with coordinates (x,y) and (x',y') is



Write the code for the function distance that computes the distance between two points.  Test this for several pairs of points for which you know the distance.

Step 4.  The main program.  (10 points or 15 points, depending on the version you do.) Whichever version of the problem you chose, you should write the main program section.  If you do the more complicated version, the main program will make three calls to the distance function before calling the area function.

You can compute the square root using the function math.sqrt from the math library.  This means that you should begin your program with the line

import math

There is another way to compute the square root using things you already know. Can you figure it out?

Optional Reading


I'm not crazy about the treatment of functions in Think, Python, since the author begins in Chapter 3 by writing functions that have no return value---something that you will rarely do---and does not discuss functions that return a value ('fruitful functions', in his terminology) until Chapter 6, after a lot of other material is introduced.  With that warning, Chapter 3 and Section 6.1 are relevant, and in fact Section 6.1 is very useful for this assignment.

What to Hand In:

Prepare the two .py files with the solutions to the programming problems, put them in a folder named with your first initial, last name and the number of the assignment, zip the folder, and submit through Canvas. Make sure your name appears in a comment in the .py files.


(The illustration at the top of this assignment is a photograph of an instrument for doing complex calendar calculations, built by Erasmus Habermel, a famous maker of scientific instruments, around 1600, not long after the introduction of the Gregorian Calendar.)