Assigned: Tuesday,
August 28

Due: Thursday, September 6 at 11 PM

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.

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.)

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.

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.

- 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.)
- 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.)
- Take the adjusted year divided by 100. This is the century. (The century is the first two digits of the year.)
- 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.)
- 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.)

- 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.
- 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.

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.

)

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

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,

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?

You might recall that the distance between two points with coordinates (x,y) and (x',y') is

You can compute the square root using the function

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

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

(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.)