Difference between revisions of "CSC111 Homework 12 2015b"
(→Requirements) |
(→Moodle Submission) |
||
Line 183: | Line 183: | ||
<br /> | <br /> | ||
<br /> | <br /> | ||
+ | <showafterdate after="20151216 12:00" before="20151231 00:00"> | ||
+ | =Solution Program= | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | # hw12sol.py | ||
+ | # D. Thiebaut | ||
+ | # This program reads temperature files recorded for the UK | ||
+ | # and prompts the user for a year and a month | ||
+ | # (on 2 separate lines, year first, month second). It then outputs | ||
+ | # the city in the UK that got the most amount of rain for this year-month | ||
+ | # combination. | ||
+ | # Examples | ||
+ | # >>> | ||
+ | # please enter year: 2000 | ||
+ | # please enter month: 1 | ||
+ | # -*- | ||
+ | # 245.4 Dunstaffnage | ||
+ | # >>> | ||
+ | # please enter year: 1940 | ||
+ | # please enter month: 12 | ||
+ | # -*- | ||
+ | # 187.5 Eskdalemuir | ||
+ | # | ||
+ | # | ||
+ | |||
+ | # the list of city names, and their associated temperature files | ||
+ | temp = [ ('Aberporth', 'aberporthdata.txt'), | ||
+ | ('Armagh', 'armaghdata.txt'), | ||
+ | ('Ballypatrick Forest', 'ballypatrickdata.txt'), | ||
+ | ('Bradford', 'bradforddata.txt'), | ||
+ | ('Braemar', 'braemardata.txt'), | ||
+ | ('Camborne', 'cambornedata.txt'), | ||
+ | ('Cambridge NIAB', 'cambridgedata.txt'), | ||
+ | ('Cardiff Bute Park', 'cardiffdata.txt'), | ||
+ | ('Chivenor', 'chivenordata.txt'), | ||
+ | ('Cwmystwyth', 'cwmystwythdata.txt'), | ||
+ | ('Dunstaffnage', 'dunstaffnagedata.txt'), | ||
+ | ('Durham', 'durhamdata.txt'), | ||
+ | ('Eastbourne', 'eastbournedata.txt'), | ||
+ | ('Eskdalemuir', 'eskdalemuirdata.txt'), | ||
+ | ('Heathrow', 'heathrowdata.txt'), | ||
+ | ('Hurn', 'hurndata.txt'), | ||
+ | ('Lerwick', 'lerwickdata.txt'), | ||
+ | ('Leuchars', 'leucharsdata.txt'), | ||
+ | ('Lowestoft', 'lowestoftdata.txt'), | ||
+ | ('Manston', 'manstondata.txt'), | ||
+ | ('Nairn', 'nairndata.txt'), | ||
+ | ('Newton Rigg', 'newtonriggdata.txt'), | ||
+ | ('Oxford', 'oxforddata.txt'), | ||
+ | ('Paisley', 'paisleydata.txt'), | ||
+ | ('Ringway', 'ringwaydata.txt'), | ||
+ | ('Ross-on-Wye', 'rossonwyedata.txt'), | ||
+ | ('Shawbury', 'shawburydata.txt'), | ||
+ | ('Sheffield', 'sheffielddata.txt'), | ||
+ | ('Southampton', 'southamptondata.txt'), | ||
+ | ('Stornoway Airport', 'stornowaydata.txt'), | ||
+ | ('Sutton Bonington', 'suttonboningtondata.txt'), | ||
+ | ('Tiree', 'tireedata.txt'), | ||
+ | ('Valley', 'valleydata.txt'), | ||
+ | ('Waddington', 'waddingtondata.txt'), | ||
+ | ('Whitby', 'whitbydata.txt'), | ||
+ | ('Wick Airport', 'wickairportdata.txt'), | ||
+ | ('Yeovilton', 'yeoviltondata.txt') ] | ||
+ | |||
+ | def getStats(): | ||
+ | """Function provided in the homework. It is used | ||
+ | as a seed for accessing all the files""" | ||
+ | |||
+ | print( " %20s: Number of lines" % "UK City" ) | ||
+ | count = 1 | ||
+ | # access each pair in the list, and display the | ||
+ | # file name and the number of lines in each one. | ||
+ | for pair in temp : | ||
+ | name = pair[0] | ||
+ | fileName = pair[1] | ||
+ | file = open( fileName, 'r' ) | ||
+ | print( "%2d: %20s: %5d lines" % | ||
+ | ( count, name, len( file.readlines() ) ) ) | ||
+ | count += 1 | ||
+ | file.close() | ||
+ | |||
+ | |||
+ | def findRainiest( year, month ): | ||
+ | """Reads all the files, and look for the line | ||
+ | containing the given year and month, and records | ||
+ | the rain amount for that month/year""" | ||
+ | |||
+ | #print( "year = ", year, "month = ", month ) | ||
+ | |||
+ | # create an empty list | ||
+ | list = [] | ||
+ | |||
+ | # iterate through each pair | ||
+ | for pair in temp : | ||
+ | name = pair[0] | ||
+ | fileName = pair[1] | ||
+ | |||
+ | # open the file | ||
+ | file = open( fileName, 'r' ) | ||
+ | |||
+ | # read it, one line at a time | ||
+ | for line in file: | ||
+ | |||
+ | # remove junk, skip invalid files | ||
+ | line = line.strip().replace( '*', '' ) | ||
+ | if len( line ) <= 1: | ||
+ | continue | ||
+ | if not line[0] in ['1', '2' ]: | ||
+ | continue | ||
+ | fields = line.split() | ||
+ | |||
+ | if len( fields ) < 7: continue | ||
+ | |||
+ | # do we have our month and year? | ||
+ | if fields[0].strip()==year and fields[1].strip()==month \ | ||
+ | and fields[5].strip() != "---": | ||
+ | |||
+ | # yes, we did find the month and year, and the temp | ||
+ | # is not ---, so add it to our list as a tuple which | ||
+ | # has the temperature first, so we can easily find the | ||
+ | # largest one. | ||
+ | list.append( | ||
+ | ( float( fields[5].strip() ), fileName ) ) | ||
+ | break | ||
+ | file.close() | ||
+ | |||
+ | # did we find anything? If not, return an empty list | ||
+ | if len( list ) == 0: | ||
+ | return [] | ||
+ | |||
+ | # sort and reverse, so rainiest month is first | ||
+ | list.sort() | ||
+ | list.reverse() | ||
+ | |||
+ | |||
+ | # extract rainiest month | ||
+ | mostRain = list[0][0] | ||
+ | newList = [] | ||
+ | |||
+ | # extract all the cities that have the same value (just in case) | ||
+ | for i in range( len( list ) ): | ||
+ | rain, file = list[i] | ||
+ | if rain == mostRain: | ||
+ | newList.append( (rain, file.replace( 'data.txt', '' ) ) ) | ||
+ | |||
+ | # return a list of tuples (rain, cityName) | ||
+ | return newList | ||
+ | |||
+ | |||
+ | def getYearMonth(): | ||
+ | """get the year and month from the user. Robust enough | ||
+ | to detect invalid inputs.""" | ||
+ | |||
+ | # get year first | ||
+ | while True: | ||
+ | year = input( "please enter year: ") | ||
+ | try: | ||
+ | int( year ) | ||
+ | break | ||
+ | except ValueError: | ||
+ | print( "Invalid year, please try again!" ) | ||
+ | |||
+ | # get month second | ||
+ | while True: | ||
+ | month = input( "please enter month: " ) | ||
+ | |||
+ | try: | ||
+ | m = int( month.strip() ) | ||
+ | except ValueError: | ||
+ | print( "Invalid month, please try again! ") | ||
+ | continue | ||
+ | |||
+ | if not ( 1 <= m <= 12 ): | ||
+ | print( "Invalid month, please try again!" ) | ||
+ | else: | ||
+ | break | ||
+ | |||
+ | # display the divider string | ||
+ | print( "-*-" ) | ||
+ | return year.strip(), month.strip() | ||
+ | |||
+ | def main(): | ||
+ | # get year and month from user. | ||
+ | year, month = getYearMonth() | ||
+ | maxRainList = findRainiest( year, month ) | ||
+ | |||
+ | # display result. | ||
+ | for rain, city in maxRainList: | ||
+ | print( rain, city.capitalize() ) | ||
+ | |||
+ | |||
+ | main() | ||
+ | |||
+ | |||
+ | |||
+ | </source> | ||
+ | </showafterdate> | ||
<br /> | <br /> | ||
<br /> | <br /> |
Latest revision as of 21:09, 3 December 2015
--D. Thiebaut (talk) 17:56, 2 December 2015 (EST)
Your assignment is due on the last day of class, 12/15/15, at 11:55 p.m.
Contents
Your Assignment
- Download this file: AllUKTemperatures.zip
- Save the file in a folder where you will be developing your program.
- Unzip the zip file. You should get 37 text files. You should recognize one of them as a file we have played with before.
- Store the (undocumented) Python program below in the same folder. It will access all the files and display some statistics about them (and it is a good seed for the program you have to write for this assignment):
# seedHw12.py
# D. Thiebaut
# reads several temperature files from the U.K. and displays
# some statistics about each one.
temp = [ ('Aberporth', 'aberporthdata.txt'),
('Armagh', 'armaghdata.txt'),
('Ballypatrick Forest', 'ballypatrickdata.txt'),
('Bradford', 'bradforddata.txt'),
('Braemar', 'braemardata.txt'),
('Camborne', 'cambornedata.txt'),
('Cambridge NIAB', 'cambridgedata.txt'),
('Cardiff Bute Park', 'cardiffdata.txt'),
('Chivenor', 'chivenordata.txt'),
('Cwmystwyth', 'cwmystwythdata.txt'),
('Dunstaffnage', 'dunstaffnagedata.txt'),
('Durham', 'durhamdata.txt'),
('Eastbourne', 'eastbournedata.txt'),
('Eskdalemuir', 'eskdalemuirdata.txt'),
('Heathrow', 'heathrowdata.txt'),
('Hurn', 'hurndata.txt'),
('Lerwick', 'lerwickdata.txt'),
('Leuchars', 'leucharsdata.txt'),
('Lowestoft', 'lowestoftdata.txt'),
('Manston', 'manstondata.txt'),
('Nairn', 'nairndata.txt'),
('Newton Rigg', 'newtonriggdata.txt'),
('Oxford', 'oxforddata.txt'),
('Paisley', 'paisleydata.txt'),
('Ringway', 'ringwaydata.txt'),
('Ross-on-Wye', 'rossonwyedata.txt'),
('Shawbury', 'shawburydata.txt'),
('Sheffield', 'sheffielddata.txt'),
('Southampton', 'southamptondata.txt'),
('Stornoway Airport', 'stornowaydata.txt'),
('Sutton Bonington', 'suttonboningtondata.txt'),
('Tiree', 'tireedata.txt'),
('Valley', 'valleydata.txt'),
('Waddington', 'waddingtondata.txt'),
('Whitby', 'whitbydata.txt'),
('Wick Airport', 'wickairportdata.txt'),
('Yeovilton', 'yeoviltondata.txt') ]
def getStats():
""" displays the name of each file, followed by the number of lines
in each one.
"""
print( " {0:20}: Number of lines".format( "UK City" ) )
count = 1
for pair in temp :
name = pair[0]
fileName = pair[1]
file = open( fileName, 'r' )
print( "{0:2}: {1:20}: {2:5} lines" . format( count, name, len( file.readlines() ) ) )
count += 1
file.close()
def main():
getStats()
main()
- Run the program. You should get an output of this form:
UK City: Number of lines
1: Aberporth: 876 lines
2: Armagh: 1932 lines
3: Ballypatrick Forest: 630 lines
4: Bradford: 1272 lines
5: Braemar: 660 lines
6: Camborne: 424 lines
7: Cambridge NIAB: 660 lines
8: Cardiff Bute Park: 436 lines
9: Chivenor: 696 lines
10: Cwmystwyth: 626 lines
11: Dunstaffnage: 511 lines
12: Durham: 1608 lines
13: Eastbourne: 660 lines
14: Eskdalemuir: 1236 lines
15: Heathrow: 792 lines
16: Hurn: 684 lines
17: Lerwick: 997 lines
18: Leuchars: 684 lines
19: Lowestoft: 1188 lines
20: Manston: 870 lines
21: Nairn: 996 lines
22: Newton Rigg: 660 lines
23: Oxford: 1932 lines
24: Paisley: 660 lines
25: Ringway: 714 lines
26: Ross-on-Wye: 997 lines
27: Shawbury: 816 lines
28: Sheffield: 1572 lines
29: Southampton: 1751 lines
30: Stornoway Airport: 1686 lines
31: Sutton Bonington: 660 lines
32: Tiree: 1032 lines
33: Valley: 997 lines
34: Waddington: 804 lines
35: Whitby: 628 lines
36: Wick Airport: 1200 lines
37: Yeovilton: 592 lines
Question
Write a program called hw12.py that will read these files (you can modify these original files for debugging, but your submitted program will be tested with copies of my originals) and prompt the user for a year and a month (on 2 separate lines, year first, month second) and will output the city in the UK that got the most amount of rain for this year-month combination.
Here are some examples:
>>> ================================ RESTART ================================ >>> please enter year: 2000 please enter month: 1 -*- 245.4 Dunstaffnage >>> ================================ RESTART ================================ >>> please enter year: 1940 please enter month: 12 -*- 187.5 Eskdalemuir >>> ================================ RESTART ================================ >>> please enter year: 1900's Invalid year, please try again! please enter year: hello? Invalid year, please try again! please enter year: 2000 please enter month: january Invalid month, please try again! please enter month: 20 Invalid month, please try again! please enter month: 1 -*- 245.4 Dunstaffnage >>> ================================ RESTART ================================ >>> please enter year: 2020 please enter month: 1 -*-
Requirements
- Your program should prompt for the year first, and the month second.
- Your program should allow years that are only integers. It is acceptable for the year to be outside the range of years found in the data files.
- Your program should accept only month that are numbers in the range 1 to 12.
- Your program should output a "-*-" after the successful input of the year and month (Thanks to Dave Marshall for figuring out this neat trick to easily separate input from output).
- Your program should not crash if the year entered is not found in the files. In this case there is no output after the -*- string.
- Your program should output the rain data (largest amount of rain recorded) and the city where this record was measured.
Recommendations
- Use the good programming tips and techniques we have seen in class recently!
Moodle Submission
- Submit your program in the HW 12 PB 1 section, on Moodle.
<showafterdate after="20151216 12:00" before="20151231 00:00">
Solution Program
# hw12sol.py # D. Thiebaut # This program reads temperature files recorded for the UK # and prompts the user for a year and a month # (on 2 separate lines, year first, month second). It then outputs # the city in the UK that got the most amount of rain for this year-month # combination. # Examples # >>> # please enter year: 2000 # please enter month: 1 # -*- # 245.4 Dunstaffnage # >>> # please enter year: 1940 # please enter month: 12 # -*- # 187.5 Eskdalemuir # # # the list of city names, and their associated temperature files temp = [ ('Aberporth', 'aberporthdata.txt'), ('Armagh', 'armaghdata.txt'), ('Ballypatrick Forest', 'ballypatrickdata.txt'), ('Bradford', 'bradforddata.txt'), ('Braemar', 'braemardata.txt'), ('Camborne', 'cambornedata.txt'), ('Cambridge NIAB', 'cambridgedata.txt'), ('Cardiff Bute Park', 'cardiffdata.txt'), ('Chivenor', 'chivenordata.txt'), ('Cwmystwyth', 'cwmystwythdata.txt'), ('Dunstaffnage', 'dunstaffnagedata.txt'), ('Durham', 'durhamdata.txt'), ('Eastbourne', 'eastbournedata.txt'), ('Eskdalemuir', 'eskdalemuirdata.txt'), ('Heathrow', 'heathrowdata.txt'), ('Hurn', 'hurndata.txt'), ('Lerwick', 'lerwickdata.txt'), ('Leuchars', 'leucharsdata.txt'), ('Lowestoft', 'lowestoftdata.txt'), ('Manston', 'manstondata.txt'), ('Nairn', 'nairndata.txt'), ('Newton Rigg', 'newtonriggdata.txt'), ('Oxford', 'oxforddata.txt'), ('Paisley', 'paisleydata.txt'), ('Ringway', 'ringwaydata.txt'), ('Ross-on-Wye', 'rossonwyedata.txt'), ('Shawbury', 'shawburydata.txt'), ('Sheffield', 'sheffielddata.txt'), ('Southampton', 'southamptondata.txt'), ('Stornoway Airport', 'stornowaydata.txt'), ('Sutton Bonington', 'suttonboningtondata.txt'), ('Tiree', 'tireedata.txt'), ('Valley', 'valleydata.txt'), ('Waddington', 'waddingtondata.txt'), ('Whitby', 'whitbydata.txt'), ('Wick Airport', 'wickairportdata.txt'), ('Yeovilton', 'yeoviltondata.txt') ] def getStats(): """Function provided in the homework. It is used as a seed for accessing all the files""" print( " %20s: Number of lines" % "UK City" ) count = 1 # access each pair in the list, and display the # file name and the number of lines in each one. for pair in temp : name = pair[0] fileName = pair[1] file = open( fileName, 'r' ) print( "%2d: %20s: %5d lines" % ( count, name, len( file.readlines() ) ) ) count += 1 file.close() def findRainiest( year, month ): """Reads all the files, and look for the line containing the given year and month, and records the rain amount for that month/year""" #print( "year = ", year, "month = ", month ) # create an empty list list = [] # iterate through each pair for pair in temp : name = pair[0] fileName = pair[1] # open the file file = open( fileName, 'r' ) # read it, one line at a time for line in file: # remove junk, skip invalid files line = line.strip().replace( '*', '' ) if len( line ) <= 1: continue if not line[0] in ['1', '2' ]: continue fields = line.split() if len( fields ) < 7: continue # do we have our month and year? if fields[0].strip()==year and fields[1].strip()==month \ and fields[5].strip() != "---": # yes, we did find the month and year, and the temp # is not ---, so add it to our list as a tuple which # has the temperature first, so we can easily find the # largest one. list.append( ( float( fields[5].strip() ), fileName ) ) break file.close() # did we find anything? If not, return an empty list if len( list ) == 0: return [] # sort and reverse, so rainiest month is first list.sort() list.reverse() # extract rainiest month mostRain = list[0][0] newList = [] # extract all the cities that have the same value (just in case) for i in range( len( list ) ): rain, file = list[i] if rain == mostRain: newList.append( (rain, file.replace( 'data.txt', '' ) ) ) # return a list of tuples (rain, cityName) return newList def getYearMonth(): """get the year and month from the user. Robust enough to detect invalid inputs.""" # get year first while True: year = input( "please enter year: ") try: int( year ) break except ValueError: print( "Invalid year, please try again!" ) # get month second while True: month = input( "please enter month: " ) try: m = int( month.strip() ) except ValueError: print( "Invalid month, please try again! ") continue if not ( 1 <= m <= 12 ): print( "Invalid month, please try again!" ) else: break # display the divider string print( "-*-" ) return year.strip(), month.strip() def main(): # get year and month from user. year, month = getYearMonth() maxRainList = findRainiest( year, month ) # display result. for rain, city in maxRainList: print( rain, city.capitalize() ) main()
</showafterdate>