Testklausur python-101, Do 2024-12-12 Lösung#

Testklausur, Teil des Leistungsnachweises von Python-101, WS 2024, Prof. Dr. Johannes Busse

WICHTIG: Dieses Jupyter Notebook ist in der Klausur python-101 lediglich ein erlaubtes Hilfsmittel unter vielen anderen Hilfsmitteln, ähnlich einem anonym benutzbaren Taschenrechner: Es wird ausschließlich die Papier-Version der Klausur bewertet.

Also: Übertragen Sie alle Ergebnisse aus dem Notebook auf Papier. (Ihre Eingaben im Notebook werden vom Dozenten nur im Ausnahmefall eingesehen – etwa dann, wenn er wissen will, ob eine interessante Lösung auch wirklich läuft. Aber bewertet wird dennoch nur die Papierklausur.)

Dauer der Klausur:

  • 30 Minuten

  • plus 10 Minuten Karenzzeit zum Übertragen der Ergebnisse auf Papier.

Vorbereitung#

(1) Speichern Sie diese Datei unter einem neuem Namen ab, Dateinamenskonvention: s-mmuster_testklausur_2024-11-22. (Jetzt können Sie Sie jederzeit auf die unveränderte Originalklausur zurückgreifen – etwa dann, falls Sie versehentlich etwas löschen).

(2) Tragen Sie Name, Vorname, MatNr etc. ein:

  • in der Papierklausur: Auf dem letzten Blatt “Persönliche Angaben” angeben, damit ich anonym korrigieren kann.

  • in der elektronischen Version NICHT angebeben, sondern anonym benutzen – ähnlich wie einen Taschenrechner.

HINWEIS: Diese Testklausur ermöglicht es den Studierenden insbesondere, die Technik des Exahm-Raums kennenzulernen. Inhaltlich erhebt die Testklausur nur bedingt den Anspruch, für Umfang und Schwierigkeit ein Beispiel zu geben.

Aufgabe 1a (2 Pkte)#

Gegeben:

  • eine Liste von Zahlen, z.B. l = [ 1, 1, 2, 3, 5, 8, 13, ... ].

Gesucht:

  • eine Auswahl-Liste l2 aller geraden Zahlen aus der Liste l.

Lösen Sie mit List Comprehension!

# Kontext
l = [ 1, 1, 2, 3, 5, 8, 13 ]
l2 = []
# Ihre Lösung


l2 = [ x for x in l if x%2 == 0 ] #...

print(l2)
[2, 8]
# Test
l2 == [2, 8]
True

Aufgabe 1b (3 Pkte)#

Gegeben:

  • eine Liste von Strings Werten, z.B.

      l = [ 1, 2, 3.14, "Hallo" ]
    

Gesucht:

  • eine Auswahl-Liste l2 aller Werte aus der Liste l:

    • falls das Listenelement eine Zahl ist, ist der Wert die Zahl selbst

    • falls das Listenelement ein String ist, ist der Wert die Länge des Strings.

# Kontext
l = [ 1, 2, 3.14, "Hallo" ]
# Ihre Lösung

l2 = []
for  x in l:
    if isinstance(x, str): l2.append(len(x)) #...
    elif isinstance(x, (int, float)): l2.append(x) #...
    else: print(f"unbekannter Typ {type(x)=}") #...


l2
[1, 2, 3.14, 5]
# test
l2 == [1, 2, 3.14, 5]
True

Aufgabe 2 (2 Pkte)#

gegeben:

  • eine Funktion primzahlzerlegung(), die die Primzahlzerlegung einer (Integer-) Zahl z ausdruckt.

gesucht:

  • diese Primzahlzerlegung als Liste

Aufgabe:

  • Verändern Sie die folgende Funktion primzahlzerlegung(z) so, dass sie die Primzahlzerlegung mehr ausdruckt, sondern auch als Liste zurückgibt!

# TBD Klausur: ...-Zeilen komplett entfernen, Aufgabe auch: die richtigen Änderungsstellen identifizieren

# hier Ihre Lösung
def primzahlzerlegung(z):
    Teiler = 2
    l = [] #...
    while z > 1:
        if z % Teiler == 0:
            #print(Teiler)
            l.append(Teiler) #...
            z = z / Teiler
        else:
            Teiler = Teiler + 1
    return l #...
# ausprobieren
Zahl = 60
primzahlzerlegung(Zahl)
[2, 2, 3, 5]
# Test
primzahlzerlegung(Zahl) == [ 2, 2, 3, 5 ]
True

Aufgabe 3 (3 Pkte)#

Mit 2 Würfeln können wir alle Würfelsummen zwischen 2 und 12 würfeln.

gegeben:

  • Wir würfeln 100 mal mit 2 Würfeln, addieren die Würfel, und zählen, wie oft jede Würfelsumme auftaucht:

    w = {4:4, 7:16, 6:17, 8:15, 12:3, 9:19, 11:9, 10:9, 5:8}
    

Gesucht:

  • Menge pech_gehabt: Welche Würfelsummen kommen trotz 100 mal würfeln nicht vor?

Lösen Sie mit Mengen-Operatoren und mit Set-Comprehension!

# Kontext
w = {4:4, 7:16, 6:17, 8:15, 12:3, 9:19, 11:9, 10:9, 5:8}
pech_gehabt = set()
# hier Ihre Lösung
# Mengen

pech_gehabt = set(range(2,13)) - set(w.keys()) #...

print(pech_gehabt)
{2, 3}
# hierIhre Lösung
# Comprehension
pech_gehabt = { x for x in range(2,13) if x not in w } #...

print(pech_gehabt)
{2, 3}
# Test
pech_gehabt == {2, 3}
True

Aufgabe 3b (2 Pkte)#

gegeben:

  • Ein Dict aus Aufgabe 3a: Gewürfelt wird sehr oft mit 2 Würfeln; für jede Würfelsummen wird gezählt, wie oft sie auftritt.

gesucht:

  • w_max: Welche Würfelsumme fällt am häufigsten und wie oft?

Hinweis: Falls mehrere Würfelsummen am häufigsten auftreten ist die Lösung nicht eindeutig. Es darf dann eine beliebige dieser Würfelsummen genannt werden.

# Kontext
w = {4: 4, 7: 16, 6: 17, 8: 15, 12: 3, 9: 19, 11: 9, 10: 9, 5: 8}
# hier Ihre Lösung:
# ergänzen Sie den Code!

w_max = 0
max = 0

for k,v in w.items():
    if v > max:
        max = v #...
        w_max = k #...
 
print( f"{w_max=}, {max=}")
w_max=9, max=19
# Test
w_max == 9, max == 19
(True, True)

Zusatzfrage (2 Zusatzpunkte):

  • Welche Würfelsumme erwarten Sie häufiger: die 3 oder die 7? Wie viel mal häufiger? (mit kurzer Begründung)

  • Welche Verteilung von Würfelsummen erwarten Sie?

Aufgabe 4 (4 Pkte)#

Sei fib(x) der der x-te Wert der Fibonacci-Folge [ 1, 1, 2, 3, 5, 8, 13, ... ] also z.B. fib(6) == 13. (Wie in Python üblich hat das erste Element den Index 0)

Wenn man sehr häufig auf diese Werte zugreifen will bietet es sich an, für diese Funktion eine Funktionstabelle zu erstellen, d.h. technisch ein Dict zu erstellen:

 fib_dict = {0: 1, # entsprict fib(0) == 1
             1: 1, 
             2: 2, 
             3: 3, 
             4: 5, 
             5: 8, 
             6: 13, # entspricht fib(6) == 13
             # usw
             }

Dieses Dict kann man dann statt einer Funktion verwenden, Beispiel: fib_dict[6] == 13.

Aufgabe:

  • Vervollständigen Sie die folgende Funktion generate_fib_dict(n), die für ein gegebenes n solch ein fib_dict erzeugt.

# hier Ihre Lösung:
# ergänzen Sie den Code!

def generate_fib_dict(n):
    ergebnis = { 0:1, 1:1 }
    for x in range(2, n+1): ergebnis[x] = ergebnis[x-1] + ergebnis[x-2] #...
        
    return ergebnis
# exemplarische Aufrufe
for i in range(7):
    print(generate_fib_dict(i))
{0: 1, 1: 1}
{0: 1, 1: 1}
{0: 1, 1: 1, 2: 2}
{0: 1, 1: 1, 2: 2, 3: 3}
{0: 1, 1: 1, 2: 2, 3: 3, 4: 5}
{0: 1, 1: 1, 2: 2, 3: 3, 4: 5, 5: 8}
{0: 1, 1: 1, 2: 2, 3: 3, 4: 5, 5: 8, 6: 13}
# Test für n==6:
generate_fib_dict(6) == {0: 1, 1: 1, 2: 2, 3: 3, 4: 5, 5: 8, 6: 13}
True

Aufgabe 5 (3 Pkte)#

gegeben: zwei Dicts, z.B.

 d1 = { 1:'a', 2:'b', 3:'c' }
 d2 = {        2:'X', 3:'Y', 4:'Z' }

gesucht: eine Funktion dict_join(x,y), die zwei Dicts verbindet:

  • alle key:value-Paare, die nur in d1 vorkommen

  • plus alle key:value-Paare aus d2

In obigem Beispiel also

 d12 = { 1:'a', 2:'X', 3:'Y', 4:'Z' }

Man sieht: alle key:value aus d1, die auch in d2 enthalten sind, werden durch d2 überschrieben.

Eine Lösung wäre z.B. update() oder merge(), aber die sind hier nicht erlaubt.

Ausführliche Lösungsmöglichkeiten siehe z.B. https://favtutor.com/blogs/merge-dictionaries-python

# Kontext
d1 = { 1:'a', 2:'b', 3:'c' }
d2 = {        2:'X', 3:'Y', 4:'Z' }
# hier Ihre Lösung:
# ergänzen Sie den Code!

def dict_join(x,y):
    ergebnis = x.copy()
    for k,v in y.items(): #...
        ergebnis[k] = v #...
    return ergebnis
# Aufruf
d12 = dict_join(d1, d2)
d12
{1: 'a', 2: 'X', 3: 'Y', 4: 'Z'}
# Test
d12 == {1: 'a', 2: 'X', 3: 'Y', 4: 'Z'}
True

Aufgabe 6 (3 Pkte)#

gegeben:

  • ein Dict sport, das über die Sportarten von Menschen Auskunft gibt:

Schwierigkeit hier: Die Sportarten sind nur als String angegeben, durch Komma getrennt. (In einer Excel-Tabelle würde man so z.B. ganz hässlich ein Multi-Value-Feld simulieren.)

gesucht:

  • ein schöneres Dict sport2, das die Sportarten als Liste angibt

# Kontext
sport = { "Anna": "Lesen, Joggen, Musik",
         "Ben": "Musik, Joggen, Schwimmen",
         "Charlie": "Lesen, Musik" }
# hier Ihre Lösung


sport2 = { k: [ s.strip() for s in v.split(",") ] for k,v in sport.items()  } #... ;-)
# ausprobieren
sport2
{'Anna': ['Lesen', 'Joggen', 'Musik'],
 'Ben': ['Musik', 'Joggen', 'Schwimmen'],
 'Charlie': ['Lesen', 'Musik']}
# Test
sport2 == {'Anna': ['Lesen', 'Joggen', 'Musik'],
 'Ben': ['Musik', 'Joggen', 'Schwimmen'],
 'Charlie': ['Lesen', 'Musik']}
True

Aufgabe 7 (3 Pkte)#

gegeben:

  • ein Dict sport2, das über die Sportarten von Menschen Auskunft gibt.

gesucht:

  • ein Dict mensch_sport, das für jede Sportart angibt, von wem sie ausgeübt wird.

# Kontext
sport2 = {'Anna':    ['Lesen', 'Joggen', 'Musik'],
          'Ben':     ['Musik', 'Joggen', 'Schwimmen'],
          'Charlie': ['Lesen', 'Musik']}
# hier Ihre Lösung:
# ergänzen Sie den Code!

mensch_sport = {}

for mensch, sportarten in sport2.items():
    for s in  sportarten: #...
        if s not in mensch_sport: #...
            mensch_sport[s] = []  #...
        mensch_sport[s].append(mensch)  #...

# was kommt 'raus?
mensch_sport
{'Lesen': ['Anna', 'Charlie'],
 'Joggen': ['Anna', 'Ben'],
 'Musik': ['Anna', 'Ben', 'Charlie'],
 'Schwimmen': ['Ben']}
# Test
mensch_sport == {'Lesen': ['Anna', 'Charlie'],
 'Joggen': ['Anna', 'Ben'],
 'Musik': ['Anna', 'Ben', 'Charlie'],
 'Schwimmen': ['Ben']}
True

Persönliche Angaben#

Familienname:

Vorname:

Matrikelnummer:

Studiengang:

Drittversuch?