Python Exercises lab 3

As with previous labs you are expected to write up your experiments and observations in your logbook.

3.1 Prerequisites and learning outcomes

Before attempting this lab you must be able to write programs which:

When you have completed this lab you will be able to write programs which:

3.2 Tuples to store and assign multiple values.

a. Copy and paste the following program into a file, save it as tuple.py and run it until you have successfully got the program to give you success and failure messages:

print "How many wheels has a Reliant Robin, and"
print "what colour are post-boxes painted in Ireland ?"
print 'to answer 2 and red you would enter (2,"red")'
attempt=tuple(input())
correct=(3,"green")
if attempt==correct:
        print "all answers are right"
else:
        print "one or more wrong answer"

Note (1.) how use of the input() function allows more complex Python objects (these can include Python code) to be read into a program.

Note (2.) how the == test allows for the testing of equality between complex objects.

b. Question: Why might using input() instead of raw_input() be dangerous if your Python program obtained its input from a web page ?

c. Think of another question to add to the above program so that it tests correct answers to 3 questions instead of 2. Modify the program accordingly and test it works correctly.

d. Carry out an experiment to assign 3 values "Fred",33 and 1.92 to 3 variables, name,age and height using a single Python command. Print out the 3 variables.

3.3 Use of lists to manipulate sets of values.

a. Perform a list assignment using the Python command line to assign the first 4 prime numbers 2,3,5 and 7 to a list called primes. Hint: you will need to use square brackets [] to assemble the list.

b. Append the 5th prime number (11) to this list using the append() method. Print out the primes list.

c. Create another list called: b of the 6th to the 8th prime numbers ( which are 13, 17 and 19). Add b to the end of primes to create a new list c (adding primes and b together using the + operator). Write what happens when you print c.

d. Append the list b to the end of the list primes (using the append() method ). Write down what happens when you print primes in your logbook. (Explanation: a list item can itself be a list in Python).

e. Print the value primes[5][2] . If you carried out the above exercises correctly this should print the value 19. Experiment with other indexes so that you print 17 or 13 in a similar way. Explain in your logbook how you can index an element within a list of lists.

3.4 Use of slices to obtain parts of lists and to manipulate lists.

a. Assign a list to a reference a , containing a regular sequence of 5 - 8 elements, such that if you knew the first 3 elements you would be able to predict the rest. E.G: [3,6,9,12,15,21,24] .

(Hint: don't just use my values, make sure you choose your own. If you could learn programming by blindly following a teacher's instructions, it would be easier for a teacher to instruct (program) a machine to write its own programs than it would be to teach a student (with an imperfect memory) how to do this. Given (a.) that no teacher can program a computer to write its own programs and (b.) that no student has a perfect memory, this proves that learning programming requires the student to do more than just follow a teachers instructions.)

b. Using a slice operation assign 2 elements from the middle of your sequence: e.g. 12 and 15 to another list called c .

c. Take a backup of your list a in b by assigning:   b=a  You might need to copy the backup in b back to a if you screw a up.

d. Using the del operator twice on indexed elements of list a, remove the 2 elements from the middle of a that you assigned into the list c. E.G if you had (blindly) used the above values your list might now look like: [3,6,9,18,21,24].

e. Using a slice assignment operation, restore the list a to its original sequence by inserting list c into the middle of list a.

Write down in your logbook the Python commands which you used to do this.

3.5 Use of range() to generate lists containing sequences of integers.

a. Pick a starting number, an ending number and a step, which forms a sequence I have not yet given to you as an example. Write these numbers into your logbook as the first 3 columns in a table. In the 4th column of your table write the range() command which you can use in Python to generate the list sequence which starts with your starting number and ends before your ending number using the required step. Repeat this process writing at least 4 rows in your table with different starting numbers, different ending numbers and different steps. Make sure there are at least 2 ascending sequences (steps > 0) and at least 2 descending sequences (steps < 0) in your table. Make sure you test the range commands in your 4th column.

b. Run the following program:

for i in range(1000000):
   print i,
   if i>100: break
Time how long it takes to complete approximately using a watch. Now change the function: range() to the function: xrange() with everything else the same and run it and time it again. Which version of this program ran faster ? If you can't tell any difference, increase the range by multiplying it by 10 until you can tell the difference. Write down in your logbook the size of range required to tell a difference and approximate timings (e.g. range(10000000) about 15 seconds, xrange(10000000) less than a second).

Why do you think there might be a difference ? If you don't know or are not sure, look up the Python library documentation for range(), xrange() and other built-in functions from http://www.python.org/doc/lib/built-in-funcs.html . Write down in your logbook your explanation for why xrange() is quicker at handling part of a very large range.

3.6 Use of for loops to iterate through predefined lists of objects

a. Create a list made up of all the following 4 lower-case words, 1 word per list item: ["the","dead","parrot","sketch"] . Assign this list to a reference called: parrot . Write and save (as for1.py ) a short program using a for loop, which prints out each word in turn, with the first letter capitalised, together with the length of each word. Your output should look like this:

The 3
Dead 4
Parrot 6
Sketch 6

Hint: you can split a string into 2 substrings using 2 slices. You can get a capitalised copy of one sub string using the .upper() method which is available if you import string . You can rejoin 2 substrings together again using the + operator.

b. Save a copy of this program as for2.py. Edit it so that each time you go through the list and print a word you print one more uppercase letter than the previous word. Your output should look like this:

The
DEad
PARrot
SKETch

To do this you will need an integer reference which counts the number of times you have been through the loop.

3.7 Use while loops to iterate until satisfactory exit conditions are obtained.

a. Copy and paste the following program into a file stats.py and run it to get the total and average of 4 numbers:

total=0.0 # accumulated total
input=1 # starts true
values=0 # number of values input by user
print "enter numbers each followed by <enter> and 0 to stop "
while input :
	input=float(raw_input(": "))
	total+=input # adds input to total
	if input: values+=1 # adds 1 if input is not zero
print "total: %.2f" % total
if values : # avoids possible divide by zero
	print "average: %.2f" % (total/values)

Then modify the program so that it gives the square root of the mean of the squares of the numbers, instead of the mean. You can obtain a square root as follows:

>>> import math
>>> math.sqrt(10)
3.1622776601683795

b. In excercise 2.15 you wrote a program to improve upon a guess for the square root of a number. This stored the number, low and high points of the range within which the square root must exist and current best guess in a file. In order to keep improving on this guess you had to run the program manually repeatedly to store the values stated above in an external file.

Using this program as a starting point, save another version of it (e.g. sqrt2.py) and use a while loop to keep automatically improving upon your guess until the square of your guess is no more than .000001 greater or less than the original number. Finally print out your guess at the square root, and the value obtained using math.sqrt() . There is no need to use an external file for this version.

3.8 Use break within loops to program more flexible loop exit conditions.

a. In the section 3.9 of the notes ( breaking out of a loop early) there is an example program which obtains a number from the user between 1 and 10. Copy and paste this program and save it as valstring.py . Modify this program so that it prompts the user for a name. The name, to be valid, must be within the alphabetic range Aaa to Zzz, and must have 3 or more letters. The program should loop until valid input is provided by the user.

b. Using your answer to question 3.7 b. , the purpose of this exercise is to see how close you can now get your successive approximation program to the real square root while preventing your program from going into an infinite loop. Change the loop exit test to while 1: (this loops infinitely), and insert a counter and suitable if and break statements within the loop body, so that the loop exits automatically after 100 iterations. See if the result you get from this version of your program is improved if your program runs for 1000 iterations.

Modify this program so that you store the previous guess and compare it to the current one, and exit either if there is no change in the guess, or if you have exceeded a large enough number of iterations such that there is likely to be little improvement in your guess.

3.9 Program design exercise

Design a program which a census enumerator can use to tabulate the numbers and percentages of dwellings with particular numbers of occupants in a road with any number of dwellings. The output must appear in a table like the one below:

Occupants	0	1	2	3	4	5	6	>6
No. dwellings	2	3	7	9	6	4	2	2
Percentage 	5.7%	8.6%	20.0%	25.7%	17.1%	11.4%	5.7%	5.7%

Dwellings with more than 6 occupants are considered to be overcrowded, and are to be output under a single column ( >6). The data input part of the program must request the number of occupants from 0 to 7 (7 being any house with more than 6 occupants) or -1 to quit.

Your program should use an 8-item list with indexes from [0] to [7] to count the numbers of houses with particular numbers of occupants. At the start of the program initialise the 8 list values to 0 ( oc=[0]*8 will do this). The user of the program inputs numbers between 0 - 7 . Finally when occupancies for all houses on the street are entered, the user inputs -1. The program outputs a table like the one above, and then exits. The table above might result from inputting a value for the number of occupants in each house in a street with 25 dwellings.

Your input and output stages must use seperate loops.