Testklausur python-101, Mo 2024-06-17#

WICHTIG: Dieses Jupyter Notebook ist in der Klausur python-101 lediglich ein erlaubtes Hilfsmittel unter vielen anderen Hilfsmitteln, ähnlich einem anonym benutzbaren Taschenrechner. Zwar wird dieses Notebook technikbedingt zeitweise gespeichert, aber es gibt keine Verbindung zu Ihrer Person. Insbesondere können ihre Eingaben im Notebook vom Dozenten nicht eingesehen und auch nicht bewertet werden.

Also: Übertragen Sie alle Ergebnisse aus dem Notebook auf Papier. Es wird ausschließlich die Papier-Version der Klausur bewertet.

Dauer der Klausur:

  • 60 Minuten

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

Name, Vorname, MatNr etc.:

  • in der Papierklausur: Nur 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 der Klausur typisch zu sein.

Zur realistischen Teilnahme an dieser Testklausur am 2024-06-17 drucken Sie sich die Papier-Version dieser Klausur bitte selbst aus und bringen Sie diese dann mit:

Operatoren#

gegeben seien die folgenden Variablen:

l = [ 1, 2, 3 ]
hallo = "Hallo!"
s = { "a", "l", "o"  }

gesucht: Verwenden Sie obige Variablen sowie eine geeignete Programmierung, um die Tests auf Gleichheit Wahr zu machen. Beispiel:

"Hallo!Hallo!" == ...
# Lösung:
"Hallo!Hallo!" == 2 * hallo
True

Jetzt sind Sie dran:

"allo" == ...
... # 
False
'!ollaH' == ...
... # 
False
'H_a_l_l_o_!' == ...
... # 
False
{ "H", "!" } == ...
... # 
... # 
False
['H', 'a', 'l', 'l', 'o', '!'] == ...
... # 
False
['1', '2', '3'] == ...
... # 
False

“Schnittliste” von Listen#

gegeben: zwei Listen, z.B.

l1 = [ 1, 2, 3, 2, 1 ]
l2 = [ 2, 3, 4, 5 ]

Die “Schnittliste” von zwei Listen sei definiert als alle Elemente von Liste 1, die auch in Liste 2 enthalten sind. Im Gegensatz zu einer Schnittmenge können die Elemente einer Liste mehrfach auftreten, und auch die Reihenfolge bleibt gleich.

def listen_schnittmenge(x, y):
    ... # 
    return ergebnis
listen_schnittmenge( l1, l2 ) == [2, 3, 2]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[11], line 1
----> 1 listen_schnittmenge( l1, l2 ) == [2, 3, 2]

Cell In[10], line 3, in listen_schnittmenge(x, y)
      1 def listen_schnittmenge(x, y):
      2     ... # 
----> 3     return ergebnis

NameError: name 'ergebnis' is not defined

Dictionary: Werte addieren#

gegeben:

  • ein Dict von Würfelpunkten, z.B.

punkte = { "Anna": [ 2, 1, 6, 4 ], "Peter": [ 6, 3, 1, 2 ] }

gesucht:

  • ein zweites Dict, das zu jedem Spieler die Summe der Punkte angibt.

... # 
punkte_summe == {'Anna': 13, 'Peter': 12}
True

Dictionary: Gewinner ermitteln#

gegeben:

  • ein Dict von aufsummierten Würfelpunkten, z.B.

punkte = {'Anna': 7, 'Peter': 12, 'Charly': 15, 'Mary': 7, 'Tim': 13 }

Teil 1#

gesucht:

  • der Name des Gewinners, hier: des Spielers (m/w/d) mit den meisten Punkten

Lösung 1, vereinfachte idealisierte Annahme: Es gibt genau einen Spieler mit einer maximalen Punktzahl. Grundgerüst für einen Lösungsansatz mit konventioneller Schleife (aber jede andere Lösung ist auch ok, ggf. sogar besser):

m = 0
gewinner = None
for spieler, p in punkte.items():
    ... # 
        ... # 
        m = p
gewinner == 'Charly'
True

Teil 2#

Spielziel jetzt: Gewonnen haben jetzt alle Spieler mit einer minimalen Punktzahl.

Lösung 2, realistische Annahme: Mehrere Spieler können die gleiche minimale Punktzahl haben, wir erhalten also eine Menge von Gewinnern.

Lösungsidee: Minimale Punktzahl bestimmen, dann Menge der Spieler mit minimaler Punktzahl erzeugen. Aber man kann es natürlich auch ganz anders machen.

... # 
... # 
{'Anna', 'Mary'}

Dictionary invertieren#

gegeben:

  • ein Dictionary von Postleitzahlen, Beispiel:

d = { "Landshut": [ 84030, 84032, 84028 ], "Dingolfing": [ 84130 ] }

gesucht:

  • ein inverses Dictionary, mit dem man bei einer gegebenen Postleitzahl den zugehörigen Ort nachschlagen kann.

d_invers = ...
... # 
d_invers == {84028: 'Landshut', 84130: 'Dingolfing', 84030: 'Landshut', 84032: 'Landshut'} # Reihenfolge ist egal
True

Textdatei auswerten#

Der Metadaten-Abschnitt (der sog. Header) einer Email besteht aus einer Reihe von Attribut-Wert-Paaren.

In einer Text-Datei kann man den Header zeilenweise so notieren, Beispiel (vereinfacht):

header = """Date: Thu, 13 Jun 2024
User-Agent: Mozilla Thunderbird
Content-Language: de-DE
To: Johannes Busse <busse@haw-irgendwo.de>
Subject: test 09.29
"""

Beobachtungen:

  • In jeder Zeile kommt ": " genau ein mal vor.

  • Jedes Attribut kommt höchstens ein mal vor.

Aufgabe Teil 1#

gegeben:

  • eine einzelne Zeile des Headers; Beispiel:

z2 = "Content-Language: de-DE"

gesucht:

  • solch eine Zeile als eine Liste [ <Attribut>, <Wert> ]

... # 
z2_liste == [ "Content-Language", "de-DE" ]
True

Aufgabe Teil 2#

Voraussetzung:

  • eine Lösung zu Teil 1: Python Code, der einen Attribut-Wert-String aw_string (wie z.B. z2) in eine Liste [ <Attribut>, <Wert> ] verwandelt.

gesucht:

  • die Lösung zu Teil 1 in eine Funktion aw(aw_string) eingepackt

  • Rückgabewert der Funktion ist nicht die Liste [ <Attribut>, <Wert> ], sondern der erste und der zweite Wert (das Attribut und sein Wert) aus dieser Liste

def aw(aw_string):
    ... # 
    return attribut, wert
z2 = "Content-Language: de-DE"
aw(z2) == ('Content-Language', 'de-DE')
True

Aufgabe Teil 3#

(Diese Teilaufgabe ist für die Klausur zu umfangreich, aber für die Klausurvorbereitung zuhause sollte es gut machbar sein, siehe die Kompetenzanforderungen unter https://www.jbusse.de/jvdp-jb/python-101-kompetenzen-a1.html )

gegeben:

  • der komplette E-Mail Header als String, siehe oben

gesucht:

  • der Header als ein Dictionary header_dict

header = """Date: Thu, 13 Jun 2024
User-Agent: Mozilla Thunderbird
Content-Language: de-DE
To: Johannes Busse <busse@haw-irgendwo.de>
Subject: test 09.29"""

konventionelle Lösung:

zeilen = header.split("\n")
header_dict = {}
for z in zeilen:
    ... # 
    ... # 
    # im Ergebnis hier so etwas wie header_dict[...] = ...
header_dict == {'Date': 'Thu, 13 Jun 2024',
 'User-Agent': 'Mozilla Thunderbird',
 'Content-Language': 'de-DE',
 'To': 'Johannes Busse <busse@haw-irgendwo.de>',
 'Subject': 'test 09.29'}
True

noch eine Lösung mit Comprehensions, hier als Einzeiler:

header_dict = ...
... # 
header_dict == {'Date': 'Thu, 13 Jun 2024',
 'User-Agent': 'Mozilla Thunderbird',
 'Content-Language': 'de-DE',
 'To': 'Johannes Busse <busse@haw-irgendwo.de>',
 'Subject': 'test 09.29'}
True

Persönliche Angaben#

Familienname:

Vorname:

Matrikelnummer:

Studiengang:

Drittversuch?