\(\renewcommand\AA{\unicode{x212B}}\)
Solutions To Exercises¶
Exercise 1¶
- Write a program that prints out the square of the first 20 integers in a block such that the block is a rectangle of size 4x5. (Hint: One method uses the - %(modulo) operator to test if a number is a multiple of another number. The answer is the remainder of the division of the lhs into whole parts, e.g. 4 % 1 = 0, 4 % 2 = 0, 4 % 3 = 1, 4 % 4 = 0)
# Write a program that prints out the square of the first
# 20 integers a block such that the block has a dimension of 4x5.
for i in range(1,21):
    print(str(i*i).center(3),end=' ') # center is a function for strings that centers the contents to the given width
    if i % 4 == 0:
        print()
# ------------ Produces -------------
# 1   4   9   16
# 25  36  49  64
# 81 100 121 144
#169 196 225 256
#289 324 361 400
Exercise 2¶
- Write a program that prints out the first 25 Fibonacci numbers. (The Fibonacci sequence starts as with - 0,1and next number is the sum of the two previous numbers)- Extend the program to also print the ratio of successive numbers of the sequence. 
 
# prev_2 - One before previous number
# prev_1 - Previous number
prev_2, prev_1 = 0, 1
# Already have first 2 terms above
print(prev_2)
print(prev_1)
# Now the next 23 terms (range(0,23) will run the loop 23 times)
for i in range(0,23):
    current = prev_2 + prev_1
    # Ratio to previous
    ratio = float(current)/prev_1
    print(str(current) + " ratio to previous= " +str(ratio))
    # Move the previous markers along one for the next time around
    prev_2 = prev_1
    prev_1 = current
Exercise 3¶
- Starting with your solution to exercise 2, rewrite your code so that you have a function called - fibthat accepts a number. The function should compute a fibonacci sequence containing this many elements and return them as a list.
# Write a program that builds a list of the first 20 Fibonacci numbers, then
## Use the list to print out the value of the ratio of successive numbers of the sequence,
##   printing out the final value.
## Extend the program so that the Fibonacci list is calculated in a function that takes the
##   number of required values as a parameter and returns the list.
# Function to calculate the first n fibonacci numbers
# and return them as a list
def fib(nfibs):
    if nfibs == 0:
        return []
    elif nfibs == 1:
        return [0]
    else:
        pass
    # First two numbers
    fibs = [0,1]
    if nfibs == 2:
        return fibs
    for i in range(2, nfibs):
        fibs.append(fibs[i-2] + fibs[i-1])
    return fibs
#### fib ends here ####
# Print out successive ratio remembering that the first number is a zero
nfibs = 20
fib_nums = fib(nfibs)
for i in range(1,nfibs):
    try:
        numerator = fib_nums[i]
        denominator = fib_nums[i-1]
        ratio = float(numerator)/denominator
    except ZeroDivisionError:
        print('Warning: Invalid ratio: ' + str(numerator) + '/' + str(denominator))
    else:
        print('Ratio ' + str(numerator) + '/' + str(denominator) + ': ' + str(ratio))
##### Produces #####
#Warning: Invalid ratio: 1/0
#Ratio 1/1:  1.0
#Ratio 2/1:  2.0
#Ratio 3/2:  1.5
#Ratio 5/3:  1.66666666667
#Ratio 8/5:  1.6
#Ratio 13/8:  1.625
#Ratio 21/13:  1.61538461538
#Ratio 34/21:  1.61904761905
#Ratio 55/34:  1.61764705882
#Ratio 89/55:  1.61818181818
#Ratio 144/89:  1.61797752809
#Ratio 233/144:  1.61805555556
#Ratio 377/233:  1.61802575107
#Ratio 610/377:  1.61803713528
#Ratio 987/610:  1.61803278689
#Ratio 1597/987:  1.61803444782
#Ratio 2584/1597:  1.6180338134
#Ratio 4181/2584:  1.61803405573
Exercise 4¶
- Write a program that creates a dictionary and initializes it with 5 names/ID pairs. - Create a function that prints out the dictionary as a 2 columns: the first being the key and the second the value 
- Update the dictionary with another 5 name/values and reprint the table, making sure you understand the ordering within the map 
 
# Write a program that creates a dictionary and initializes it with 5 names/ID pairs.
## Create a function that prints out the dictionary in a nicely formatted table;
## Update the dictionary with another 5 name/values and reprint the table,
##   making sure you understand the ordering within the map.
def formatLine(cola, colb, width):
    return cola.center(width) + '|' + colb.center(width)
# A simple two cloumn print out
def outputStore(store):
    print('Phonebook contains {} entries:'.format(len(store)))
    # Do a quick sweep to find out the longest name
    col_width = 0
    for k in store:
        if len(k) > col_width:
            col_width = len(k)
    col_width += 5
    # Header
    print('-'*col_width*2)
    print(formatLine('Name', 'Ext.', col_width))
    print('-'*col_width*2)
    for k ,v in store.items():
        print(formatLine(k, str(v), col_width))
phone_book = {'Martyn Gigg' : 1234, 'Joe Bloggs' : 1233, 'Guido Van Rossum' : 4321, 'Bob' : 2314, 'Linus Torvalds' : 4132 }
outputStore(phone_book)
# Update Dictionary (replacing one person's phone number
new_entries = {'Bjarne Strousoup' : 9876, 'Bill Gates' : 9898, 'Steve Jobs' : 7898, \
              'Bob' : 9871, 'Dave' : 7098 }
phone_book.update(new_entries)
outputStore(phone_book)
#------------- Produces --------------------
#Phonebook contains 5 entries:
#------------------------------------------
#         Name        |         Ext.
#------------------------------------------
#         Bob         |         2314
#      Joe Bloggs     |         1233
#    Linus Torvalds   |         4132
#   Guido Van Rossum  |         4321
#     Martyn Gigg     |         1234
#Phonebook contains 9 entries:
#------------------------------------------
#         Name        |         Ext.
#------------------------------------------
#   Guido Van Rossum  |         4321
#     Martyn Gigg     |         1234
#      Steve Jobs     |         7898
#   Bjarne Strousoup  |         9876
#      Joe Bloggs     |         1233
#    Linus Torvalds   |         4132
#         Dave        |         7098
#      Bill Gates     |         9898
#         Bob         |         9871
Exercise 5¶
- Build a list containing the 5 filenames of the text files that are going to be used. (Hint: Can be done by hand or using the os.listdir(‘dirpath’) function in the os module) 
- Add a bogus file name that doesn’t exist to the list (so that we have to do some error handling) 
- Loop over the list and for each file (Remember here that we have a non existent file in the list and calling open on this will result in an IOError exception that needs to be dealt with) - Open the file; 
- Loop over each line; 
- Split the line up into sections (Hint: The string has a - .split()function that splits the string on whitespace and gives back a list with each section as an element of the list)
- Convert the second column value into an float 
- Keep track of the values for each line and compute an average for the file. 
 
- Finally, print out a list of file,average-value pairs 
## Exercise 5
#   1.  Build a list containing the 5 filenames of the text files that are going to be used.
#       (Hint: Can be done by hand or using the os.listdir() function in the os module)
#   2. Add a bogus file name that doesn't exist to the list (so that we have to do some error handling)
#   3. Loop over the list and for each file (Remember here that we have a non existent file in the list and calling open
#      on this will result in an IOError exception that needs to be dealt with)
#         1. Open the file;
#         2. Loop over each line;
#         3. Split the line up into sections (Hint: The string has a .split() function that splits the string on
#            whitespace and gives back a list with each section as an element of the list)
#         4. Convert the second column value into an integer
#         5. Keep track of the values for each line and compute an average for the file.
#   4. Finally, print out a list of file,average-value pairs
import os
file_dir = "C:\\MantidInstall\\data\\"
file_names = os.listdir(file_dir)
file_names.append('nonexistant.txt')
average_store = {}
print('Computing average for log files in directory "' + file_dir + '"')
for name in file_names:
    # Skip all no text files
    if name.endswith('.txt') == False:
        continue
    try:
        file_handle = open(os.path.join(file_dir,name), 'r')
    except IOError:
        print('\tError: No such file: "' + name + '". Skipping file')
        continue
    print('\tReading file',name)
    # At this point we have an open file
    average = 0.0
    nvalues = 0
    line_counter = 1
    for line in file_handle:
        columns = line.split()
        if len(columns) == 2:
            average += float(columns[1])
            nvalues += 1
        else:
            print('\tWarning: Unexpected file format encountered in file {0}  on line {1}'.format(name,line_counter))
        line_counter += 1
    average /= nvalues
    average_store[name] = average
    file_handle.close()
# Print out file averages
column_width = 30
print('')
print('-'*column_width*2)
print('File'.center(column_width) + '|' + 'Average'.center(column_width))
print('-'*column_width*2)
for key, value in average_store.items():
    print(key.center(column_width) + '|' + str(value).center(column_width))