Python Exercises lab 2

2.1 Prerequisites and learning outcomes

By now you should be able to:

If you have not done all of these things go back to lab 1, complete it and restart this lab when you have finished lab 1.

In future weeks you will be expected to have completed and written up the previous lab before starting on the next one. To make best use of the tutorial time it is your responsibility to stay up to date and to catch up with previous week's labs if you are unable to attend a tutorial.

At the end of this lab you should be able to write simple Python programs which:

2.2 Obtaining program user input

open your circle.py program, modify it, paying particular attention to the second line, so that it reads:

import math
radius=int(raw_input("Please enter a radius"))
area=math.pi*radius**2
print "For a circle of radius %s the area is %s" % (radius,area)

and save it as circle2.py . Run this program, and when prompted for a radius input: 2 If your program runs correctly you should see the output:

>>> For a circle of radius 2 the area is 12.5663706144

(Assuming it is run using import circle or in an environment such as pywin that outputs to the python command line system. If it is run by other means you won't get the >>> prompt, but the rest of the output should be visible.)

Run your program again for radiuses of 1 and 1.5 . Write down the results which you get in your logbook for a radius of 1 and write down the error message which you get for a radius of 1.5 .

2.3 Getting floating point input

Change line 2 of your program so that it reads:

radius=float(raw_input("Please enter a radius"))

Test your program again for input values of 1, 1.5 and 2. Write down the results in your logbook and answer the following questions in your own words in your logbook:

Does the int() built in function accept floating point (fractional) values ?

Does the float() built in function accept integer (whole number) values ?

Which built in function seems more useful for this application and why ?

Test your program again for an input value of: Fred . Write down the error message you get in your logbook exactly as it appears. Examine this message carefully and explain in your logbook how Python tells you about the location in your program where the error occurred and the kind of error which occurred.

2.4 Trapping an invalid input exception

Save your program as circle3.py and insert 2 additional lines (starting with try and except ) to help catch the ValueError without allowing it to crash your program. You will need to indent some existing lines by 2 or 4 spaces (you must do this consistently) so that your program looks like this:

import math
try:
  radius=float(raw_input("Please enter a radius"))
  area=math.pi*radius**2
  print "For a circle of radius %s the area is %s" % (radius,area)
except(ValueError):
  print "you entered invalid input"

Test your program again providing inputs: 1, 1.5 and Fred, and write the results into your logbook.

2.5 Flow control branching using if, elif and else

Open a new program file and (using copy and paste from circle2.py if you wish) input the following code and save it as if1.py

mark=float(raw_input("Please enter a mark"))
if mark >= 40:
  print "You passed"
else:
  print "You failed"

Test this program using inputs of 39, 40 and 99 and write the results in your logbook.

Adapt this program as show below and save it as if2.py .

mark=float(raw_input("Please enter a mark"))
if mark < 40:
  print "fail"
elif mark < 50:
  print "pass"
elif mark < 70:
  print "credit"
else:
  print "distinction"

Run the program 4 times with input values chosen to get the following output:

fail
pass
credit
distinction

Given that credits are awarded for marks greater than or equal to 50 and less than 70, why doesn't the test for a credit:

elif mark < 70:
  print "credit"

need to check for marks greater than or equal to 50 in addition to marks less than 70 in order to avoid awarding credits for marks not deserving credits ? Look at the whole program and write your understanding of this question and your answer in your logbook. In your logbook write down your understanding of if [test]: elif [test]: and else: if you have not yet completely done so.

2.6 Getting string input

Save the following program as string1.py :

name=raw_input("Please enter your name")
print "you entered: %s" % name

Test it using input values: Fred , 1 and 1.5 . You didn't have to say something like:

string(raw_input("Please enter your name"))

in the manner you did with circle2.py when obtaining int and float data from the keyboard, because raw_input() returns a string anyway. You had to convert a string to a float or an int when you wanted numbers, but if you both want a string and get a string no conversion is needed. Note that the strings "1" and "1.5" which worked with the above program may have looked to you just like numbers, but if you are in any doubt about whether these are numbers or strings then try modifying circle2.py as follows:

import math
radius=raw_input("Please enter a radius")
area=math.pi*radius**2
print "For a circle of radius %s the area is %s" % (radius,area)

and running this modified version with inputs of 1.5 and 1.

Excercise: carry out the above modification to circle2.py and write down in your logbook the kind of error you get and the program line in which this error is detected. Write down the line number where this design error actually occurs. (Hint: errors are very often detected in programs somewhere below the line where they really occur.)

2.7 Adding or "concatenating" strings

Save the following program as string2.py and run it:

fname=raw_input("Please enter your first name")
lname=raw_input("Please enter your last name")
print "Hello %s %s" % (fname,lname)

How would you store the combination which appears on the output for later ? Modify and save it as follows:

fname=raw_input("Please enter your first name")
lname=raw_input("Please enter your last name")
greeting= "Hello %s %s" % (fname,lname)
print greeting

Write the results of your test of the above programs in your logbook.

Here is another approach to joining strings. Save the following program as string3.py

fname=raw_input("Please enter your first name")
lname=raw_input("Please enter your last name")
name=fname+lname
print name

What did the + operator do to the 2 strings ? How would you join the 2 names together with a space between them ? (Hint: you could also add the string: " " which is a single space surrounded by quotes, and use 2 + operators to add your 3 strings) Test your solution, and write the answers in your logbook.

Excercise: a. write a program called address.py which inputs your full name and address from the keyboard (the address might include 3 lines, line1, line2 and line3 and a postcode ) and which prints out the name and address on the output like this:

Bilbo Baggins,
3 Bag End Lane,
Hobbiton,
The Shire,
HB1 QW4

Hint: if you want to output more than 1 line using a single print statement, you can use the escape \n (backslash followed by n) either within a string or added to a string to achieve this. Print this program and stick it into your logbook when you have finished.

2.8 Testing strings

Save the following program as cmpstring.py and test it :

name=raw_input("Enter your name")
if name == "Aladdin":
    print "your wish is my command!"
else:
    print "go away"

Then by rearranging the above program (always use edit/cut and paste for this kind of job, don't rewrite unless you can type quicker than use the mouse) get it to give exactly the same test results, but this time around using the != comparison operator (not equal to) intead of the == (equal to) comparison operator.

2.9 Combining comparisons using: and

Develop a program testand.py which asks for a name and a password, and prints an acceptance message if the name is "Aladdin" and the password is "sesame" . This program should print a rejection message in all other cases. This should be achieved by combining the 2 tests into 1 using the and keyword. Stick a printed copy of your program source code into your logbook.

2.10 Combining comparisons using: or

Develop a program (testor.py) that asks the user if he/she is happy. If the user enters either "y" or "Y" print a suitable greeting (e.g. "great") , otherwise a suitably compassionate reply (e.g. "sorry to hear that") . You should combine the tests for "y" and "Y" using the or keyword. Stick a printed copy of your program source code into your logbook.

2.11 Combining comparisons using: not

Save the following program into a file called not.py . The while 1: statement is an infinite loop which would go on forever if there were no break statement to end the loop. Run this program, providing input values of 0,11 and 1.

while 1:
    number=int(raw_input("enter a number between 1 and 10: "))
    if not 1 <= number <= 10:
      print "out of range, try again"
    else:
      break
print "you entered %d" % number

Write down in your logbook the effect of the keyword: not on the way the if statement handles the test: 1 <= number <= 10 .

2.12 Writing to files

Write and save a Python program which opens a file called: fileworld in the current working directory, and writes the text: 'Hello File World !' to this file. Open this file in notepad or vi or display it by some other means, so you know the file was created successfully. Write the source code for your program into your logbook.

Create a new version of the program you wrote which prompted for your name and address, so that instead of displaying user inputs for name and the various address parts on the console it writes this address label to a file called: address.txt . Make sure you test the program by checking output using Notepad etc.

2.13 Reading from files

Create a text file containing 3 numbers, one on each line, e.g:

3
5
6

Write and save a program which reads each line and converts it into a floating point object (you can use references a, b and c for to refer to these numbers). Hint: you converted keyboard input which raw_input() gave you as strings into floats by using the float() builtin function. You can do something similar to the string output by the readline() method. Print out the sum (all 3 numbers added up) and the product (all 3 numbers multiplied together) and the average (your sum divided by 3.0). When you have got it working put the source code into your logbook.

2.14 Updating a text file

Write and save a copy of a program which reads a file address.txt containing an address label similar to the kind of address file you have used before, but not containing a phone number. Your program must store the address. Add a prompt which asks the user for a telephone number. Close address.txt and reopen it in write mode, writing the address back to the same file together with a phone number.

2.15 Design Exercise: get a square root by successive approximation

Write a program which reads 4 numbers from a file called guess_file.txt .

The first, N, is a number greater than 1, e.g. 5.0 . Your program is expected to find a closer approximation to the square root of this number than your guess.

The second number, lower_limit, will start at 1.0 and is the lower limit of what the square root of N might be.

The third, upper_limit, is the upper limit of what the square root might be and starts as the same number as N.

The forth, guess, is the first guess as to the square root of N. The first guess should start at (N+1)/2.0 e.g: (5.0+1.0)/2.0 is 3.0 :

Here is what your guess_file.txt should contain before the first program run:

5.0
1.0
5.0
3.0

An algorithm which improves upon a guess for the square root of a number N works as follows:

open guess_file in read mode
input N, upper_limit, lower_limit and guess from guess_file
close guess file
print these values to screen
guess_squared = guess multiplied by itself.
if guess_squared is greater than N :
	upper_limit = guess
else if guess_squared is less than N :
	lower_limit = guess
else : # guess is equal to the square root of N
 	print the square root of N is guess
next_guess = (upper + lower)/2.0
open guess_file in write mode
output N, upper_limit, lower_limit and next_guess to guess_file
close guess file
print these values to screen

Convert the above pseudo-code algorithm into a Python program which is saved in a file called guessqrt.py . Debug it. Run it so that the upper and lower limit values stored in the guess file get closer to each other and the guess improves each time you run this program. When you have got your program working print the source code and paste this into your logbook.

Run this program a few times, each time noting down in your logbook the upper, lower and guess values. How many times do you need to run this program before the guess doesn't change by more than 0.001 (1 thousandth) ? Check your calculated square root using a calculator.

Adjust the if and else if (elif) tests in your source code so that when the difference between guess_squared and the number N is less than 0.001 the else: block is used and the guess is printed. Print the adjusted source code and paste this into your logbook, or record the adjustments made to these tests into your logbook.