Exercise 1: Heronian Triangles

During this lab, you will create and hand in 2 files (note: they have different file extensions!):

  1. breaking_python.txt - first you'll gain experience working with the interactive Python interpreter, then you'll actually try to cause errors to occur. This should take about 10-20 minutes.
  2. triangles.py - you'll look at a non-standard formula for the area of a triangle.

(No quizzes on Learn@UW this time! Just code.)


Do not post any of your code on Piazza or any other public forum. The only people who should see your code are the instructor/TAs and your partner (if you have one).

Part 0: The Interactive Python Interpreter

So far in 301, we've been writing Python code in one file and sending it to the interpreter to execute. In this assignment, you'll see how you can bypass that first step if you want.

If you're on a Mac, you'll want to find the Utilities folder in your Applications folder. Open up the Terminal application, and just type the word python in the window you see.

If you installed Python on a PC, you created a folder like this with the Python interpreter in it. Go find it and open it up directly - just double-click on the python application.

Everyone should now be looking at something like this:

This (or something very similar) is the Python interpreter. In this window, you can type Python code (like I've done in the image above) and it will execute right away. The three greater-than signs (>>>) are called the prompt, and they're there to indicate that the interpreter is ready for you to start typing.

Give it a try! Here are some expressions (and results) that you can use to test out the interpreter, but feel free to play around even more!

Note: with the interactive interpreter, we don't need to explicitly use the print command to get output, but don't forget to use it in your programs.

>>> 40 + 2

>>> 40 ** 2

>>> 40 % 2

>>> 'hi there!'
hi there!

>>> L = [0,1,2,3]
(no response from Python)

You just made a variable named L that contains a list of ints (we'll talk about lists and some of their special powers later on in the class). Python doesn't give you any output when you're using the assignment operator (=).

>>> L

This displayed the value currently stored in your variable L.

>>> 100*L + [42]*100
(a whole bunch of stuff I'm not typing out)

>>> L = 42
(no response from Python)

Remember you can reassign variables! What's the type of L's value now?

>>> type(L)
<type 'int'>

>>> L == 42

To test for equality, you use two equals signs together - this is a different operator than =, which is the assignment operator.

>>> L != 42

The != operator tests "not equal".

When you're done messing around in the interpreter, you can leave it by typing in the command quit() (make sure you include the parentheses!) at the prompt.

Part 1: Breaking Python

Programming Truth 1: You are going to encounter errors when you write code.

Programming Truth 2: This is totally okay. When you encounter an error, it's an opportunity to learn something new about Python. It's the interpreter actually protecting you. You're not going to break the computer :)

Create a file - it can be in Notepad or TextEdit, since you'll just be using it to take notes. When you save it, call it breaking_python.txt (note the file extension) so when you hand it in, we know what it is.

Now go back to the interpreter. See how many of these Python errors you can cause in 2 minutes (don't worry about getting them all). I've included some hints:

  • NameError (I don't recognize that variable!)
  • TypeError (How many times does purple go into 12?)
  • ZeroDivisionError (I think you can figure this one out.)
  • SyntaxError (That's not Python you're speaking...)
  • IndexError (But "python" only has six letters!)
  • OverflowError (Heard of a googol - 1.0 * 10**100? CAN YOU MAKE IT BIGGER??)

When you cause an error, add a comment with the error type and the message from the interpreter to your breaking_python.txt file and on the next line, include the code you used to cause the error. Something like this:

# OperatorError: operator '*' is not defined (note: this doesn't actually happen here)
27 * 'purple' / 3

Side note: overflow is what happens on computers as a result of the fact that all numbers are represented in fixed numbers of ones and zeros (binary). An 8-bit number has a maximum of 8 digits (e.g. 1001 1011, or 155 in decimal), which means it can't represent any numbers higher than 1111 1111 (255) - the number 256 (1 0000 0000) would cause the representation to overflow the number of digits it has. Modern computers usually use 64 bits for ints, but you might have noticed that Python will sometimes attach an L to the end of really long integers - this is a value of type long, used for really big ints, and if you get too big for a long, Python will just crash instead of giving you an error. This is why I suggest a float for the OverflowError ;)

Part 2: Triangles!

We're going to keep the code pretty simple for now, but things will get a bit more difficult soon!

Frequently when you're considering a triangle, you know its side lengths, but picking a base and calculating its height so you can use the standard area formula is a pain. Luckily, Hero of Alexandria has your back with a super slick formula.

Let's get started:

  • Create a new python module in a project in LiClipse and name it triangles.
  • Copy and paste this code into your editor (I've started it out for you):
# Author:
# Pair Partner:

# Lab 1: Triangle Hero

import math

def area(a,b,c):
	""" This will eventually have your implementation of Hero's Formula,
	    but for now it just returns zero all the time. Fix that!
	return 0

# TODO: get user input for the three sides (step 1)

# TODO: check that all sides are valid (step 3)

# TODO: check that the triangle itself is valid (step 3)

# TODO: calculate and display the perimeter (step 2)

# TODO: calculate and display the area of the triangle (step 2)

# TODO: check whether the triangle is Heronian (step 3)

You can complete this program in any order you wish, but I'll walk you through the steps that I followed. In either case, however, your final program output should look exactly like the output at the end of Step 3 - same words, same ordering, same punctuation. (This makes it easier for the TAs to grade.)

Step 1: Hero's Formula

One of the first things I usually do in a program is complete all the mathematical formulas. In this case, it's the area calculation:

where s is defined as half the perimeter, or:

Once you have that implemented, you should test it! Add a few lines of code under the function to call it with different values for a, b, and c:

Testing with 2,3,4:
Testing with 3,4,5:
Testing with 5,12,13:

Note: Your final program submission should not contain this output - it's merely temporary, for testing purposes.

Step 2: User Input

Now, rather than hard-coding your values, get them from the user - remember that raw_input() gives you back a string, so you will probably need to do some type casting.

Take the values you've read in from the user and use those to call your function. While you're at it, you might want to also calculate and show the perimeter of the triangle.

Note: I show user input in these examples as bold, blue text. Anything in that style should NOT be output by your program.

a: 5
b: 12
c: 13
The perimeter of the triangle is 30
The area of the triangle is 30.0

You may assume that all side lengths the user inputs are integers.

Step 3: Checking Things

We're just starting to learn about conditions and different behavior in different situations, so let's get some practice. There are three different things for you to check in this program:

  1. Did the user give you all valid side lengths? If they tried to tell you that a side was 0 or negative, that doesn't make a lot of sense (and might end up getting you a square root of a negative number if you try to calculate the area!) - if they do this, display an error message and exit your program:

    a: 0
    b: 1
    c: 2
    You can't have a side that's 0!
  2. Did the user give you a valid triangle? In order to actually make a triangle, the sum of every pair of sides should be greater than the remaining side. Don't believe me? Grab a ruler and draw a triangle with sides of lengths 2", 3", and 5".

    If they do that, same deal - display an error message and exit your program:

    a: 2
    b: 3
    c: 5
    That's not a real triangle!
  3. Was the triangle the user entered Heronian? All of our triangles for this program will have integer sides, but a Heronian triangle is one whose sides and area are all integers. If the user enters such a triangle, you should say so!

    a: 2
    b: 3
    c: 4
    The perimeter of the triangle is 9
    The area of the triangle is 2.90473750966
    a: 3
    b: 4
    c: 5
    The perimeter of the triangle is 12
    The area of the triangle is 6.0
    You found a Heronian triangle!

Reminder: your final output should look exactly like the sample output above! This makes it easier for the TAs to grade.

Submitting your files

At the top of both your breaking_python.txt and triangles.py files, add your name (and if you coded with a partner, their name as well) as comments, like this:

# Author:       (your name)
# Pair Partner: (your partner's name)

You'll be handing in your lab work via the course Learn@UW dropboxes. Navigate to our 301 course page, and click the Dropbox link in the top navigation bar. You should see a dropbox for Program 1 - this is where you should hand in your breaking_python.txt and triangles.py files. (If you worked in a pair, only one person will need to hand in the code.)

Note that the dropbox will close at noon on 4 February, so be sure to submit your files before then.