Python course University of Heidelberg

Solutions Day 1

03.01

In [ ]:
[4**3,2+3.4**2,complex(1,1)**2]

Or even simpler

In [ ]:
[4**3,2+3.4**2,(1+1j)**2]

03.02

In [ ]:
a = "Hello, roof world!"
word = "roof"
num = a.index(word)
chars = len(word)
print(a[:num]+a[num+chars:])

03.03

In [ ]:
s = "CAGTACCAAGTGAAAGAT"
s.count('A')
In [ ]:
a=[1,2,3]
b=[4,5,6]
c=a+b

# or

d=a
d.extend(b)
print(c,d)

04.01

In [ ]:
x=3.7
(x>3.4 and x<=6.6) or (x==2)

04.02

In [ ]:
dict={'snake':'Schlange',
      'jungle':'Dschungel',
      'lives':'lebt',
      'in':'in',
      'the':'der/die/das'}

s="The snake lives in the jungle"
for word in s.split():
    print(dict[word.lower()])

05.01

In [ ]:
for i in range(2,1000):
    is_prime=True
    for j in range(2,i):
        if (i%j==0):
            is_prime=False
    if is_prime:
        print (i)
        

05.02: Simply break the loop since it is not necessary to search further if one divisor is found.

In [ ]:
for i in range(2,1000):
    is_prime=True
    for j in range(2,i):
        if (i%j==0):
            is_prime=False
            break
    if is_prime:
        print (i)

05.03

In [ ]:
# very terse:
a, b = 0, 1
while a < 100000:
    print(a)
    #c = a + b
    #a = b
    #b = c
    a, b = b, a + b
In [ ]:
# Fibonacci sequence in a list
l=[0]
idx=0
fib=1

while fib<100000:
    l.append(fib)     # add x_i
    fib=l[idx]+l[idx+1]   # work out x_i+1
    idx=idx+1
    
print(l)

And the square Fibonaccis:

In [ ]:
# determine square Fibonaccis
l=[0]
fib=1

while fib<100000:
    l.append(fib)
    fib=l[-2]+l[-1]

# print square Fibonacci numbers
for fib in l:
    is_square=False
    for j in range(fib):
        if j*j==fib:
            is_square=True
            break
    if is_square:
        print("square number =",fib,"(="+str(j)+"*"+str(j)+")")

Solution Cryptography

In [ ]:
s='pbatenghyngvbaf lbh unir fhpprrqrq va qrpelcgvat gur fgevat'

base=ord('a') # ascii code for 'a'
decode=-13
res=''
for character in s.lower():
    if character==' ':
        t=character
    else:
        ascii=ord(character)
        t=chr(((ascii+decode)-base)%26+base) # (ascii-97)%26 in range 0 ... 25
    res+=t
print(decode,res)

The translation of ascii can also be done explicitly:

In [ ]:
s='pbatenghyngvbaf lbh unir fhpprrqrq va qrpelcgvat gur fgevat'

base=ord('a') # ascii code for 'a'
decode=-13

res=''
for character in s.lower():
    if character==' ':
        tt=ord(' ')
    else:
        ascii=ord(character)
        tt=ascii+decode
        if tt>=base+26:
            tt-=26
        elif tt<base:
            tt+=26
    res+=chr(tt)
print(decode,res)

This is the solution when first loading the alphabet into a list:

In [ ]:
s='pbatenghyngvbaf lbh unir fhpprrqrq va qrpelcgvat gur fgevat'

decode=-13

alphabet=[]
for i in range(ord('a'), ord('z')+1):
    alphabet.append(chr(i))
               
# or a very pythonic way
#alphabet=[chr(i) for i in range(ord('a'),ord('z')+1)]

decode=-13

res=''
for character in s.lower():
    if character==' ':
        tt=' '
    else:
        idx=alphabet.index(character)+decode
        if idx>=26:
            idx-=26
        elif idx<0:
            idx+=26
        tt=alphabet[idx]
    res+=tt
print(decode,res)

Determine the unkown cipher shift trying out all

In [ ]:
s='fn jyxuxprin oxa cqn rwlxwenwrnwln'
In [ ]:
base=ord('a') # ascii code for 'a'
for decode in range(-10,20):
    #decode=-13
    res=''
    for character in s.lower():
        if character==' ':
            t=character
        else:
            ascii=ord(character)
            t=chr(((ascii+decode)-base)%26+base)
        res+=t
    print(decode,res)

Note solution -7 and 17 are equivalent.

We can also try to be smart: the most common letter used in English words is the "e" (Most common letter from Oxford dictionary). So let's try to get a guess of the required decode parameter by counting letters first (will not work good for short text sequences though - why?):

In [ ]:
s='fn jyxuxprin oxa cqn rwlxwenwrnwln'

max=0
max_letter=''
for letter in s:
    count=s.count(letter)
    if count>max:
        max=count
        max_letter=letter
        
print('The letter that occured most often in the string is "'+max_letter+'" with '+str(max)+' counts.')

decode=ord('e')-ord(max_letter)
print('The most likely "decode" parameter is thus '+str(decode))

To obtain better statistics, one could also include the second most letter and so on.