Python course University of Heidelberg

Solutions Day 2

06.01

In [ ]:
def is_prime(x):
    is_prime=True
    for j in range(2,x):
        if (x%j==0):
            is_prime=False
            break
    return is_prime

is_prime(43)

06.02

In [ ]:
# here the multiplication is done explicitly
#
# note for x<0 it also returns 1
#
def factorial_loop(x):
    ans=1
    for i in range(1,x+1):
            ans*=i      
    return ans
print(factorial_loop(5))
In [ ]:
# using recursive function calls
#
# factorial_recursive stops once the returned value is 1
#
def factorial_recursive(x):
    if x<=1:
        return 1
    else:
        return x*factorial_recursive(x-1)
print(factorial_recursive(5))

06.03

In [ ]:
l = [1, 9, 4, 5, 16, 7]

def mean(x):
    return sum(x)/len(x)

print(mean(l))

Note that in Python 3, you do not necessarily need to use the float function. See part about divisons.

07.01

In [ ]:
# EDIT THE CODE BELOW

# Open file
f = open('../data/data.txt', 'r')

# Read and ignore header lines
header1 = f.readline()
header2 = f.readline()
header3 = f.readline()

jmag = {}

# Loop over lines and extract variables of interest
for line in f:
    line = line.strip()
    columns = line.split()
    name = columns[2]
    jmag[name] = float(columns[3])
    
f.close()
    
print(jmag['00424455+4116103'])

    
print('Unsorted:')
for key in jmag:
    print (key, jmag[key])

print('Sorted:')
for key in sorted(jmag):
    print (key, jmag[key])

07.02

In [ ]:
# Open file
f = open('data/autofahrt.txt', 'r')
f2 = open('autofahrt_new.txt', 'w')

# read and ignore header lines
header1 = f.readline()
header2 = f.readline()

# loop over the lines in the iterable f
for line in f:
    line = line.strip()
    columns = line.split()
    time = columns[0]
    a = columns[2]
    
    f2.write(time+' '+a+'\n')  # time and a are already strings

# close the file handles
f.close()
f2.close()

08.01

In [ ]:
import math
In [ ]:
math.cos?
In [ ]:
# math.cos takes radians
print('cos 60 deg = ', math.cos(math.radians(60)))
print('sin pi/6 = ', math.sin(math.pi/6))

08.02

In the first example, x is defined locally in the function by the assignment x=x*2. Any changes to x are therefore only made locally and not globally.

In the second example, x is not defined locally but x in the function points to the global x and any changes to x are therefore also visible outside the scope of the function. We could change the function to use a local copy of the global x and only change this copy in the local scope of the function:

def append_3(x):
    x = x.copy()
    x.append(3)
    print(x)

x = [1,2]
append_3(x)
print(x)

Now we observe the same behaviour as with the function double(x).

Practice problem temperatures

In [ ]:
%ls ../data/
%less ../data/munich_temperatures_average.txt
# [this works under unix only]
In [ ]:
d = {}
max_temp = 0
with open('../data/munich_temperatures_average.txt','r') as f:
    for line in f:
        year, temp = line.strip().split()
        s = year[0:4]              # the years are the first four characters
        
        if s not in d:             # if year not found yet, add entry to dictionary
            d[s] = []

        d[s].append(float(temp))   # note, temp is still a string
        
for year in sorted(d):
    temps = d[year]
    print(year, min(temps), sum(temps)/float(len(temps)), max(temps))

The same for the months, assuming for simplicity that each month has 30 days:

In [ ]:
month_names = {1: 'January',
               2: 'February',
               3: 'March',
               4: 'April',
               5: 'May',
               6: 'June',
               7: 'July',
               8: 'August',
               9: 'September',
               10: 'October',
               11: 'November',
               12: 'December'
              }

d={}
with open('../data/munich_temperatures_average.txt','r') as f:
    for line in f:
        year, temp = line.strip().split()
        
        frac = float(year[4:])      # subtract number of year
        month = int(12*frac) + 1      # split in 12 intervals
        
        if month not in d:                  # new month in dictionary
            d[month] = []

        d[month].append(float(temp))

for month in sorted(d):
    temps = d[month]
    print(month_names[month], min(temps), sum(temps)/float(len(temps)), max(temps))
    

There are the calendar and datetime built-in modules which may make things easier/more professional.