Aufgaben zu Runde 1: Grundlagen#

Runde 1: Flache (keine “verschachtelten”) Listen und Dicts

Über diese Aufgaben:

  • Die Aufgaben vermitteln einen Eindruck, wie typische praktische kleine Problemstellungen aussehen, die man am Ende von Runde 1 (etwa nach den ersten 6 Wochen) lösen können sollte.

  • Gelegentlich kommen Aufgaben wie diese auch als “Aufgabe 1” in den Klausuren vor. Der Zweck sit, sich etwas einzugrooven, aber eigentlich sind das KEINE typischen Klausuraufgaben.

Diese Seite liegt in zwei Versionen vor (die man nur im Detail unterscheiden kann – genaues Hinschauen erforderlich):

Aufgaben:

Loesung:

Die Aufgaben sind so gestellt, dass sie sich auf Skript-Ebene zunächst mit minimalem technischen Aufwand lösen lassen. Gleichzeitig sind sie offen genug, auch fortgeschrittenere – insbesondere generischere – Lösungsmöglichkeiten zuzulassen. Damit lassenn sie sich auch in Programmier-Praktika einsetzen, bei denen Studierende mit sehr heterogenen Vorkenntnissen teilnehmen: Es gibt kein abschließendes “fertig”, fast immer kann man es auch noch etwas eleganter oder schöner machen.

Aufgabe Grundlage Listen (ehmatthes beginners_python_cheat_sheet)#

Quelle und Lösungen für Listen siehe ehmatthes/pcc_3e (Bcklink: https://ehmatthes.github.io/pcc_3e/cheat_sheets/)

Definiere eine Liste mit den Wochentagen: Montag, Dienstag, …, Samstag, Sonntag

w = [ "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag" ]
w
['Montag',
 'Dienstag',
 'Mittwoch',
 'Donnerstag',
 'Freitag',
 'Samstag',
 'Sonntag']

Wie lautet das erste Element, das zweite, das letzte?

# Kontext
w = [ "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag" ]

# hier die Lösung entwickeln
... # 
... # 
... # 

# eigene Lösung anschauen
erstes_element, zweites_element, letztes_element
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[2], line 10
      7 ... # 
      9 # eigene Lösung anschauen
---> 10 erstes_element, zweites_element, letztes_element

NameError: name 'erstes_element' is not defined
# Test
(erstes_element, zweites_element, letztes_element) == ("Montag", "Dienstag", "Sonntag") 
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[3], line 2
      1 # Test
----> 2 (erstes_element, zweites_element, letztes_element) == ("Montag", "Dienstag", "Sonntag") 

NameError: name 'erstes_element' is not defined

Ändere den “Samstag” auf “Sonnabend”

# Kontext wie oben
# hier die Lösung entwickeln
... # 

# Test
w == [ "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Sonnabend", "Sonntag" ]
False

Füge einen neuen, nicht existierenenden Wochentag hinzu, z.B. “Sankt-Nimmerleins-Tag”

# ab hier selbstständig weitermachen

Lösche den dritten Tag aus der Liste

Lösche den Sonnabend aus der Liste

Wie viele Elemente hat die Liste jetzt?

Sortiere die Liste alphabetisch aufsteigend / absteigend

drucke (print) alle Elemente der Liste aus

Aufgabe: Grundlagen Dicts#

Quelle und Lösungen für dicts siehe ehmatthes/pcc_3e

Definiere ein Dict Liste mit den Wochentagen und ihrer Abkürzung: “Mo”: “Montag”, “Di”: “Dienstag” …

Wie heißt der Wochentag, der mit “Di” abgekürzt wird?

Füge das Key-Value-Paar “snt”: “Sankt-Nimmerleins-Tag” hinzu

Ändere den Wert des Schlüssels “Sa” auf “Sonnabend”

Lösche das Key-Value-Paar für “Mi”

drucke (print) alle Schlüssel / alle Values / alle Key-Value-Paare

Wie viele Elemente hat unser Dict?

Aufgaben zum Eingrooven#

gegeben:

  • eine Liste l von Zahlen: l = [ 3, 2, 1, 2, 3 ]

gesucht:

  • eine Liste l2 der Quadrate der Zahlen aus l

  • die Summe s2 aus l2

# Kontext
l = [ 3, 2, 1, 2, 3 ]
l2 = []
s2 = 0

# Ihr Programm
l2 = [ x*x for x in l ]#...
s2 = sum(l2)#...

# Ihr Ergebnis
l2, s2
# Test
l2 == [9, 4, 1, 4, 9],  s2 == 27

Quadratzahlen#

Gegeben:

  • Eine Liste in_bsp von Zahlen.

Gesucht:

  • Eine Funktion dq(liste), die für alle Zahlen aus in_bsp, die Vielfache von 3 sind, das Quadrat zurückliefert.

Bitte lösen Sie mit List Comprehension.

# Beispiel
in_bsp = [0, 1, 2, 3, 4]
out_bsp = [ 0, 9 ]
# dq ... dreier quadrate
def dq(liste):
    ... # 
# assert dq(in_bsp) == out_bsp

Zweitupel#

Gegeben:

  • eine Zahl n

Gesucht:

  • eine Funktion, die eine Liste aller 2-Tupel der natürlichen Zahlen von 1 bis n zurückgibt.

Bitte lösen Sie mit List Comprehension.

# Beispiel
n = 3
out_bsp = [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
def zweitupel(n):
    ... # 
# assert zweitupel(3) == out_bsp

Deltas#

Gegben:

  • eine Liste von Zahlen

Gesucht:

  • eine Funktion, die die größte Differenz zwischen zwei aufeinanderfolgenden Zahlen in dieser Liste zurückgibt.

in_bsp = [ 4, 3, 1, -2, 5]
out_bsp = 7
def deltas(l):
    ... # 
# assert deltas(in_bsp) == out_bsp

Bruchzahlen aufaddieren#

gegeben: eine Liste von Bruchzahlen, angegeben als Tupel: (1,8) wäre dann 1/8 oder 0.125.

  • z.B. [ (1,8), (-1,4), (2,4) ]

Gesucht: diese Bruchzahlen rein numerisch aufaddiert (das ist hässlich, aber nicht schwer).

Lösen Sie mit Hilfe einer Dict-Comprehension!

# b ... Brüche
b = [ (1,8), (-1,4), (2,4) ]
... # 
bsumme
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[16], line 2
      1 ... # 
----> 2 bsumme

NameError: name 'bsumme' is not defined

Aufgabe: Liste von Quadratzahlen#

Gegeben ist eine Liste von Zahlen:

z = [ 1, 2, 3, 5, 10 ]

Gesucht: Eine Liste z2 der Quadratzahlen dieser Zahlen, hier z.B. z2 == [1, 4, 9, 25, ... ]

z2 = ...
... # 



z2 == [1, 4, 9, 25, 100]
False

Aufgabe: Liste “Monate” als Strings#

Aufgabe: Gesucht ist eine Liste Monate als Strings: [ '01', '02', ..., '12' ]

Monate = ...
... # 



M = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']
Monate == M
False

Hinweis: Eine Zahl wie z.B. 3 kann man mit folgenden f-string in einen String mit führenden Nullen verwandeln:

zahl = 3
zahlstring = f'{zahl:>02}'
zahlstring
'03'

Aufgabe: Liste von Kriegen#

gegeben:

Kriege = """seit 2009: Krieg gegen die Taliban in Pakistan
2010–2011: Bürgerkrieg in der Elfenbeinküste
seit 2012: Konflikt in Mali
2013–2018: Bürgerkrieg im Südsudan
seit 2014: Krieg in der Ostukraine
seit 2023: Krieg in Israel und Gaza"""

Teilaufgabe#

gegeben:

  • obige “Liste” Kriege als String

gesucht:

  • dieser String als eine Liste von einzelnen Zeilen als Strings

K_liste = ...
... # 




K_kurz = [ 'seit 2009: Krieg gegen die Taliban in Pakistan',
'2010–2011: Bürgerkrieg in der Elfenbeinküste',
'seit 2012: Konflikt in Mali' ]
K_liste[0:3] == K_kurz
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[22], line 10
      2 # 
      7 K_kurz = [ 'seit 2009: Krieg gegen die Taliban in Pakistan',
      8 '2010–2011: Bürgerkrieg in der Elfenbeinküste',
      9 'seit 2012: Konflikt in Mali' ]
---> 10 K_liste[0:3] == K_kurz

TypeError: 'ellipsis' object is not subscriptable

Teilaufgabe#

gegeben:

  • die obige Liste K_kurz (die ersten 3 Elemente aus obiger Teilaufgabe)

gesucht:

  • eine Liste aller “Namen” von Kriegen aus K_kurz ohne Zeitangabe

K_namen = ... # Namen von Kriegen
... # 




K_namen == [' Krieg gegen die Taliban in Pakistan',
 ' Bürgerkrieg in der Elfenbeinküste',
 ' Konflikt in Mali']
False

Teilaufgabe#

gegeben:

  • obige Liste K_kurz

gesucht:

  • Eine Liste der Namen aller Kriege aus K_kurz, die noch andauern

K_kurz_andauernd = ...
... # 




K_kurz_andauernd == ['Krieg gegen die Taliban in Pakistan', 'Konflikt in Mali']
False

Aufgabe: würfeln mit 2 Würfeln#

Kontext: Es wird n mal mit zwei Würfeln gewürfelt, die Augen der beiden Würfel werden addiert, Bsp.:

2+2=4, 4+3=7, 3+3=6, 2+6=8, 2+6=8,  5+2=7, 2+2=4, 3+3=6, 6+6=12, 2+6=8,  3+6=9, 5+3=8, 5+6=11, 4+2=6, 3+5=8,  4+4=8, 3+3=6, 4+2=6, 2+5=7, 2+4=6

Teilaufgabe#

Gesucht:

  • ein Dict wuerfe, das für jeden Wurf die absolute Häufigkeit angibt

Ergänzen Sie das folgende Progrämmchen!

import random as rd
rd.seed(42) # außerhalb der Klausur besser: `None` to use current system time
n = 100     

wuerfe = ...
... # 

for i in range(n):
    a = rd.randrange(2, 7)
    b = rd.randrange(2, 7)
    wurf = a + b
    # print(f"{a}+{b}={wurf}", end=', ')
    ... # 
    ... # 
    ... # 

print(wuerfe)
Ellipsis
wuerfe == {4: 4, 7: 16, 6: 17, 8: 15, 12: 3, 9: 19, 11: 9, 10: 9, 5: 8}
False

Teilaufgabe#

gegeben:

  • obiges Dict wuerfe

gesucht:

  • ein zweites Dict wuerfe_relativ, in dem für jeden Wurf die Wurf-Häufigkeit als relative Häufigkeit in Prozent angegeben ist.

(Das geht einfach: absolute Wurf-Häufigkeit durch n teilen, dann mit 100 mulitiplizieren).

wuerfe_rel = {}
... # 





wuerfe_rel == { 4: 10.0, 7: 15.0, 6: 30.0, 8: 30.0, 12: 5.0, 9: 5.0, 11: 5.0}
False

Aufgabe: zip von Name und Alter#

gegeben:

  • zwei gleich lange Listen Name und Alter

Name = [ "Anna", "Ben", "Charly" ]
Alter = [ 23, 22, 20 ]

gesucht:

  • ein Dict, das für jeden Namen das Alter angibt

Teilaufgabe#

Lösen Sie die Aufgabe mit zip()!

Name_Alter = {}
... # 




Name_Alter
{}

Teilaufgabe#

Lösen Sie die Aufgabe ohne zip()!

... # 
Ellipsis

“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[33], line 1
----> 1 listen_schnittmenge( l1, l2 ) == [2, 3, 2]

Cell In[32], 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.

... # 
Ellipsis
punkte_summe == {'Anna': 13, 'Peter': 12}
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[36], line 1
----> 1 punkte_summe == {'Anna': 13, 'Peter': 12}

NameError: name 'punkte_summe' is not defined

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
  Cell In[38], line 5
    ... #
    ^
IndentationError: unexpected indent
gewinner == 'Charly'
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[39], line 1
----> 1 gewinner == 'Charly'

NameError: name 'gewinner' is not defined

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.

... # 
... # 

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> ]

... # 
Ellipsis
z2_liste == [ "Content-Language", "de-DE" ]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[44], line 1
----> 1 z2_liste == [ "Content-Language", "de-DE" ]

NameError: name 'z2_liste' is not defined

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

# aw ... attributwert
def aw(aw_string):
    ... # 
    return attribut, wert
z2 = "Content-Language: de-DE"
aw(z2) == ('Content-Language', 'de-DE')
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[46], line 2
      1 z2 = "Content-Language: de-DE"
----> 2 aw(z2) == ('Content-Language', 'de-DE')

Cell In[45], line 4, in aw(aw_string)
      2 def aw(aw_string):
      3     ... # 
----> 4     return attribut, wert

NameError: name 'attribut' is not defined

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'}
False

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'}
False

Aufgabe: Verbinden von zwei Dicts#

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() # optional; was macht das?
    for k,v in y.items():
        ... # 
    return ergebnis
# Aufruf
d12 = dict_join(d1, d2)
d12
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[54], line 2
      1 # Aufruf
----> 2 d12 = dict_join(d1, d2)
      3 d12

Cell In[53], line 8, in dict_join(x, y)
      6 for k,v in y.items():
      7     ... # 
----> 8 return ergebnis

NameError: name 'ergebnis' is not defined
# Test
d12 == {1: 'a', 2: 'X', 3: 'Y', 4: 'Z'}
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[55], line 2
      1 # Test
----> 2 d12 == {1: 'a', 2: 'X', 3: 'Y', 4: 'Z'}

NameError: name 'd12' is not defined

Aufgabe: Sportarten als Liste#

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

... #  ;-)
Ellipsis
# ausprobieren
sport2
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[58], line 2
      1 # ausprobieren
----> 2 sport2

NameError: name 'sport2' is not defined
# Test
sport2 == {'Anna': ['Lesen', 'Joggen', 'Musik'],
 'Ben': ['Musik', 'Joggen', 'Schwimmen'],
 'Charlie': ['Lesen', 'Musik']}
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[59], line 2
      1 # Test
----> 2 sport2 == {'Anna': ['Lesen', 'Joggen', 'Musik'],
      3  'Ben': ['Musik', 'Joggen', 'Schwimmen'],
      4  'Charlie': ['Lesen', 'Musik']}

NameError: name 'sport2' is not defined