Grundlagen, Runde 2#
Über diese Aufgaben#
Die Aufgaben vermitteln einen Eindruck, wie typische praktische kleine Problemstellungen aussehen, die man am Ende von Runde 2 (etwa nach den ersten 10 Wochen) lösen können sollte.
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.
“Verschachtelte” Listen und Dicts#
Liste von Dicts durchsuchen#
gegeben: eine Liste von Dicts, Beispiel:
hobbies = [
{'Alice': ['Lesen', 'Reisen'], 'Bob': ['Schwimmen', 'Fotografie']},
{'Alice': ['Kochen'], 'Charlie': ['Lesen', 'Tanzen']},
{'Bob': ['Skifahren'], 'David': ['Gitarre']}
]
gesucht:
Wer hat ein bestimmtes Hobby, z.b. Lesen?
Aufgabe: Schreiben Sie eine Funktion hobby_person()
, die zu einem gegebenen Hobby alle zugehörigen Personen aus hobbies
zurückgibt.
def hobby_person(gesucht, dictliste):
to_return = set()
for d in dictliste:
... #
... #
... #
return to_return
# hobby_person("Lesen", hobbies) == {'Alice', 'Charlie'}
Cell In[2], line 5
... #
^
IndentationError: unexpected indent
Vereinigungsmenge von Dicts#
gegeben: eine Liste von Dicts, Beispiel:
z.B.
dlist = [ {'a': 1, 'b': 2, 'c': 3}; d2 = {'b': 2, 'c': 99}
]
d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'b': 2, 'c': 99}
dlist = [d1, d2 ]
print(f"{dlist=}")
dlist=[{'a': 1, 'b': 2, 'c': 3}, {'b': 2, 'c': 99}]
gesucht: ein Dict dlist_union
, das für jeden Key alle Values enthält, die es in den dicts dazu gibt!
z.B.
dlist_union = {'c': {3, 99}, 'a': {1}, 'b': {2}}
Vorgehen:
(a) erzeugen Sie ein Set, das alle keys enthält
(b) initialisieren Sie
dlist_union
, dass es etwa so aussieht:{ 'a': set(), 'b': set(), ...: ...}
(c) füllen Sie dann
dlist_union
geeignet auf
# a)
allkeys = set()
... #
# allkeys == {'a', 'b', 'c'}
Ellipsis
# b)
dlist_union = {}
... #
# dlist_union == {'c': set(), 'a': set(), 'b': set()}
Ellipsis
# c)
for d in dlist:
... #
... #
# dlist_union == {'c': {3, 99}, 'a': {1}, 'b': {2}}
Cell In[6], line 4
... #
^
IndentationError: unexpected indent
Aufgabe: In welchen Monaten gibt es (k)einen Feiertag?#
Gegeben: ein Dict Feiertage
:
Feiertage = { 'Weihnachten': '24.12', 'Silvester': '31.12', 'Neujahr': '01.01',
'Erster Mai': '01.05', 'Tag der Deutschen Einheit': '03.10' }
gesucht:
eine Menge
Monate_mit_Feiertag
: In welchen Monaten gibt es einen Feiertag?eine Menge
Monate_OHNE_Feiertag
: In welchen Monaten gibt es keinen Feiertag?
Hinweis: Sie dürfen bei Bedarf gerne die folgende Liste M
benutzen.
M = ['01', '02', '03', '04', '05', '06',
'07', '08', '09', '10', '11', '12']
Monate_mit_Feiertag = ...
... #
Monate_mit_Feiertag == {'01', '05', '10', '12'}
False
Monate_OHNE_Feiertag = ...
... #
Monate_OHNE_Feiertag == {'02', '03', '04', '06', '07', '08', '09', '11'}
False
Aufgabe: Familienmitglieder und Rollen#
Gegeben ist ein Dict von Dicts, das zu Familien die Familienmitglieder und ihre Rollen angibt:
Familien = { 'Maier' : { 'Martin': 'Vater', 'Monika': 'Mutter',
'Maria': 'Tochter', 'Merle': 'Tochter' },
'Schulz': { 'Sabine': 'Mutter', 'Sarah': 'Tochter', 'Sieglinde': 'Oma' }}
gesucht:
ein Dict
Familie_Groesse
: Wie viele Familienmitglieder hat jede Familie?eine Menge
Alle_Rollen
: Welche Rollen gibt es in diesen Familien?eine Liste
Alle_Toechter
: Wie heißen die Töchter?
Familie_Groesse = ...
... #
Familie_Groesse == {'Maier': 4, 'Schulz': 3}
False
Alle_Rollen = ...
... #
Alle_Rollen == {'Mutter', 'Oma', 'Tochter', 'Vater'}
False
Alle_Toechter = ...
... #
Alle_Toechter == ['Maria', 'Merle', 'Sarah']
False
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
False
Aufgabe: Auswahl von Zahlen aus Liste#
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 Listel
.
Lösen Sie mit List Comprehension!
# Kontext
l = [ 1, 1, 2, 3, 5, 8, 13 ]
l2 = []
# Ihre Lösung
... #
print(l2)
[]
# Test
l2 == [2, 8]
False
Aufgabe: Auswahl aus Liste mit Varianten#
Gegeben:
eine Liste von Strings, z.B.
l = [ 1, 1, 2, 3, "Hallo" ]
Gesucht:
eine Auswahl-Liste
l2
aller Werte aus der Listel
: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:
... #
... #
... #
l2
[]
# test
l2 == [1, 2, 3.14, 5]
False
Aufgabe: Würfelsummen#
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
... #
print(pech_gehabt)
set()
# hierIhre Lösung
# Comprehension
... #
print(pech_gehabt)
set()
# Test
pech_gehabt == {2, 3}
False
Aufgabe: häufigste Würfelsummen#
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:
... #
... #
print( f"{w_max=}, {max=}")
w_max=0, max=0
# Test
w_max == 9, max == 19
(False, False)
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: Funktionstabelle#
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 gegebenesn
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):
... #
return ergebnis
Cell In[30], line 7
... #
^
IndentationError: expected an indented block after 'for' statement on line 6
# exemplarische Aufrufe
for i in range(7):
print(generate_fib_dict(i))
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[31], line 3
1 # exemplarische Aufrufe
2 for i in range(7):
----> 3 print(generate_fib_dict(i))
NameError: name 'generate_fib_dict' is not defined
# Test für n==6:
generate_fib_dict(6) == {0: 1, 1: 1, 2: 2, 3: 3, 4: 5, 5: 8, 6: 13}
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[32], line 2
1 # Test für n==6:
----> 2 generate_fib_dict(6) == {0: 1, 1: 1, 2: 2, 3: 3, 4: 5, 5: 8, 6: 13}
NameError: name 'generate_fib_dict' is not defined
Aufgabe: Sportarten von Menschen#
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():
... #
... #
... #
... #
# was kommt 'raus?
mensch_sport
Cell In[34], line 8
... #
^
IndentationError: unexpected indent
# Test
mensch_sport == {'Lesen': ['Anna', 'Charlie'],
'Joggen': ['Anna', 'Ben'],
'Musik': ['Anna', 'Ben', 'Charlie'],
'Schwimmen': ['Ben']}
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[35], line 2
1 # Test
----> 2 mensch_sport == {'Lesen': ['Anna', 'Charlie'],
3 'Joggen': ['Anna', 'Ben'],
4 'Musik': ['Anna', 'Ben', 'Charlie'],
5 'Schwimmen': ['Ben']}
NameError: name 'mensch_sport' is not defined
Aufgabe: zu Dict einen reverted Index bilden#
gegeben:
ein Dict
d
, das für die Tage einer Woche die Maximaltemperatur zeigt:d = { "Mo": 17, "Di": 18, "Mi": 16, "Do": 15, "Fr": 16, "Sa": 17, "So": 17 }
gesucht:
ein Dict
d2
, das für jede Maximaltemperatur eine Liste von Tagen hat, die diese Temperatur hatten. (Man benötigt so etwas regelmäßig für Such-Anwendungen).
# Kontext
d = { "Mo": 17, "Di": 18, "Mi": 16, "Do": 15, "Fr": 16, "Sa": 17, "So": 17 }
# Ihre Lösung
d2 = {}
# Lösung 1 aus der Vl, "Grundstruktur Listenbearbeitung"
for tag, temperatur in d.items():
if not temperatur in d2: # d2.keys()
d2[temperatur] = []
d2[temperatur].append(tag)
# andere Lösung: vorher schon initialisieren
d2 = {temperatur: [] for temperatur in set(d.values()) }
# jetzt gibt es schon alle keys, mit leeren Listen initialisiert
for tag, temperatur in d.items():
d2[temperatur].append(tag)
# ganz böse, schlechte Comprehension
# wegen Nebeneffekt!
# wegwerfen = [ d2[temperatur].append(tag) for tag, temperatur in d.items() ]
# Ihr Ergebnis
d2
# Test
d2 == {17: ['Mo', 'Sa', 'So'], 18: ['Di'], 16: ['Mi', 'Fr'], 15: ['Do']}
Aufgabe: zip() simuieren#
gegeben:
zwei gleich lange Listen
Wörter
undZiffern
; in ListeWörter
kommt kein Wert doppelt vor.
gesucht:
ein Dict
wort_zip
, das zu jedem Wort die zugehörige Zahl angibt
Gesucht sind zwei verschiedene Lösungen, mit und ohne zip()
# Lösung 1, mit zip()
# Kontext
Wörter = [ "eins", "oans", "zwei", "zwoa", "adin" ]
Zahl = [1, 1, 2, 2, 1 ]
wort_zahl = {}
# Ihre Lösung
wort_zahl = dict( zip(Wörter, Zahl) )
#wort_zahl = list( zip(Wörter, Zahl) )
#wort_zahl = tuple( zip(Wörter, Zahl) )
# Ihr Ergebnis
wort_zahl
# Test
wort_zahl == {'eins': 1, 'oans': 1, 'zwei': 2, 'zwoa': 2, 'adin': 1}
# Lösung 2, ohne zip()
# Kontext wie oben
Wörter = [ "eins", "oans", "zwei", "zwoa", "adin" ]
Zahl = [1, 1, 2, 2, 1 ]
wort_zahl = {}
# Ihre Lösung
# indirektes Durchgehen mit Index
for i in range( len(Wörter) ):
wort_zahl[ Wörter[i] ] = Zahl[i]
# Ihr Ergebnis
wort_zahl
# Test
wort_zahl == {'eins': 1, 'oans': 1, 'zwei': 2, 'zwoa': 2, 'adin': 1}