Practice Problem - Temperatures - Sample Solution

First we read in the data:

In [1]:
days = []
temperatures = []

for line in open('data/munich_temperatures_average.txt', 'r'):
    
    day, temperature = line.strip().split()
    
    # day and temperature are strings so we need to convert them
    # when we append them to the lists
    days.append(float(day))
    temperatures.append(float(temperature))

Now that the data has been read into two lists, we can loop through and split up the temperatures by year:

In [2]:
yearly_temperatures = {}

for i in range(len(days)):
    
    # Find the year (as an integer)
    year = int(days[i])
    
    # If the key doesn't exist in the dictionary, create it
    if not year in yearly_temperatures:
        yearly_temperatures[year] = []
        
    # Add the temperature to the list
    yearly_temperatures[year].append(temperatures[i])

Having done this, the dictionary contains for each year a list of average temperatures. We can now loop through the years and find the minimum, average, and maximum:

In [3]:
for year in yearly_temperatures:
    
    # We can store the current temperature list in a variable
    # to avoid having to write it out every time.
    t_list = yearly_temperatures[year]
    print(year, min(t_list), sum(t_list) / len(t_list), max(t_list))
1995 -13.2778 8.765600054794515 25.9444
1996 -15.5 7.22983359342466 23.8333
1997 -12.8889 8.548421924590162 21.5556
1998 -12.2222 9.245702324861876 25.5
1999 -9.83333 9.110651741758234 25.3333
2000 -16.7778 9.76544640164383 24.7778
2001 -12.1667 9.00713250874317 24.5556
2002 -11.1111 9.881714284084081 25.1111
2003 -14.3333 9.398325638356173 27.6667
2004 -10.7778 8.877015703013702 23.0
2005 -14.1111 8.224754590883188 25.1111
2006 -11.2778 9.163765467582415 25.9444
2007 -8.83333 9.768647250696379 26.2778
2008 -5.11111 9.660867162637365 24.0556
2009 -10.7778 9.37229706465753 23.2778
2010 -9.33333 8.321307882191778 25.7222
2011 -9.27778 9.691631063013695 25.5
2012 -15.4444 9.225267140821925 24.7222
2013 -7.38889 0.6455037752380951 11.1667

In this case, the dates are in the right order, but when looping over a dictionary, order is not guaranteed, so it is safer to do:

In [4]:
for year in sorted(yearly_temperatures.keys()):
    t_list = yearly_temperatures[year]
    print(year, min(t_list), sum(t_list) / len(t_list), max(t_list))
1995 -13.2778 8.765600054794515 25.9444
1996 -15.5 7.22983359342466 23.8333
1997 -12.8889 8.548421924590162 21.5556
1998 -12.2222 9.245702324861876 25.5
1999 -9.83333 9.110651741758234 25.3333
2000 -16.7778 9.76544640164383 24.7778
2001 -12.1667 9.00713250874317 24.5556
2002 -11.1111 9.881714284084081 25.1111
2003 -14.3333 9.398325638356173 27.6667
2004 -10.7778 8.877015703013702 23.0
2005 -14.1111 8.224754590883188 25.1111
2006 -11.2778 9.163765467582415 25.9444
2007 -8.83333 9.768647250696379 26.2778
2008 -5.11111 9.660867162637365 24.0556
2009 -10.7778 9.37229706465753 23.2778
2010 -9.33333 8.321307882191778 25.7222
2011 -9.27778 9.691631063013695 25.5
2012 -15.4444 9.225267140821925 24.7222
2013 -7.38889 0.6455037752380951 11.1667

Now we can try and do the same thing, but sorting by month instead of year. For simplicity, let's assume that all 12 months are the same length:

In [5]:
monthly_temperatures = {}

for i in range(len(days)):
    
    # Find the month (as an integer). This finds the fractional
    # part of the date, multiplies it by 12, and then converts
    # to an integer. We then have to add 1 to make sure it is in
    # the range 1-12 (not 0-11).
    month = int(12. * (days[i] - int(days[i]))) + 1
    
    # If the key doesn't exist in the dictionary, create it
    if not month in monthly_temperatures:
        monthly_temperatures[month] = []
        
    # Add the temperature to the list
    monthly_temperatures[month].append(temperatures[i])
In [6]:
for month in sorted(monthly_temperatures.keys()):
    m_list = monthly_temperatures[month]
    print(month, min(m_list), sum(m_list) / len(m_list), max(m_list))
1 -16.7778 -0.8494002017421606 12.2222
2 -15.4444 0.6628654298245613 11.9444
3 -7.66667 4.473989138162547 16.2778
4 -2.11111 9.276253876416819 20.7222
5 5.22222 13.979305660036161 23.1667
6 7.77778 17.20418630597015 25.1111
7 10.5 18.459178853046595 26.2778
8 9.5 18.218715287569577 27.6667
9 3.88889 13.708544866412208 22.7222
10 -1.44444 9.380126712544817 20.5
11 -7.11111 3.7421812866666655 14.1667
12 -15.5 0.22031673032490967 11.2778

If we want to show the month, we can use a dictionary:

In [7]:
MONTHS = {}
MONTHS[1] = "January"
MONTHS[2] = "February"
MONTHS[3] = "March"
MONTHS[4] = "April"
MONTHS[5] = "May"
MONTHS[6] = "June"
MONTHS[7] = "July"
MONTHS[8] = "August"
MONTHS[9] = "September"
MONTHS[10] = "October"
MONTHS[11] = "November"
MONTHS[12] = "December"
In [8]:
for month in sorted(monthly_temperatures.keys()):
    m_list = monthly_temperatures[month]
    print(MONTHS[month], min(m_list), sum(m_list) / len(m_list), max(m_list))
January -16.7778 -0.8494002017421606 12.2222
February -15.4444 0.6628654298245613 11.9444
March -7.66667 4.473989138162547 16.2778
April -2.11111 9.276253876416819 20.7222
May 5.22222 13.979305660036161 23.1667
June 7.77778 17.20418630597015 25.1111
July 10.5 18.459178853046595 26.2778
August 9.5 18.218715287569577 27.6667
September 3.88889 13.708544866412208 22.7222
October -1.44444 9.380126712544817 20.5
November -7.11111 3.7421812866666655 14.1667
December -15.5 0.22031673032490967 11.2778

You may want to look into the calendar and datetime built-in modules to see if any of the above can be made easier.