Fingerübungen 2024-03#

Mengen#

s1 = { 3, 2, 1, "a"}
s2 = { 3, "a", "c", "b" }

s3: Schnittmenge von s1 und s2

... # 
assert s3 == {3, 'a'}
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[2], line 2
      1 ... # 
----> 2 assert s3 == {3, 'a'}

NameError: name 's3' is not defined

s4: Vereinigungsmenge von s1 und s2

... # 
assert s4 == {1, 2, 3, 'a', 'b', 'c'}
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[3], line 2
      1 ... # 
----> 2 assert s4 == {1, 2, 3, 'a', 'b', 'c'}

NameError: name 's4' is not defined

s5: Differenzmenge: Alle Elemente aus s1, die nicht in s2 enthalten sind

... # 
assert s5 == {1, 2}
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[4], line 2
      1 ... # 
----> 2 assert s5 == {1, 2}

NameError: name 's5' is not defined

s6 symmetrische Differenz: Alle Elemente aus s1, die nicht in s2 enthalten sind, sowie alle Elemente aus s2, die nicht in s1 enthalten sind

... # 
assert s6 == {1, 2, 'b', 'c'}
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[5], line 2
      1 ... # 
----> 2 assert s6 == {1, 2, 'b', 'c'}

NameError: name 's6' is not defined

Strings#

Was wird ausgegeben? (Manche der folgenden Opertationen werfen einen Fehler: Schreiben Sie einfach FEHLER hin.)

l_11 = "abc"
l_12 = "XYZ"
hallo = "Hallo Welt!"
l_11 + l_12
'abcXYZ'
l_11 - l_12
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[8], line 1
----> 1 l_11 - l_12

TypeError: unsupported operand type(s) for -: 'str' and 'str'
l_11 * 2
'abcabc'

Strings#

Gegeben ist der String hallo = "Hallo Welt!".

Erzeugen Sie mit einem Einzeiler die folgenden Ausgaben:

hallo[0:3]
'Hal'
hallo[::-1]
'!tleW ollaH'
hallo.split()
['Hallo', 'Welt!']

Einfache String-Programme#

Gegeben ist ein Gedicht in der folgenden Form:

haiku = "Der alte Teich. Ein Frosch springt hinein. Das Geräusch des Wassers."

Erzeugen Sie aus haiku eine Liste von Listen.

... # 
haiku_zeilen
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[14], line 2
      1 ... # 
----> 2 haiku_zeilen

NameError: name 'haiku_zeilen' is not defined
h_dict = {
    0 : ... ,
    1 : {"zeile": "Uralter Teich. | Ein Frosch springt hinein. | Plop.",
        "block": ['Uralter Teich. ', ' Ein Frosch springt hinein. ', ' Plop.'],
        "groß": ['Uralter', 'Teich.', 'Ein', 'Frosch', 'Plop.']}}
z = "Uralter Teich. | Ein Frosch springt hinein. | Plop.".split("|")
z
['Uralter Teich. ', ' Ein Frosch springt hinein. ', ' Plop.']
[w for zeile in z for w in zeile.split() if w[0].isupper()]
['Uralter', 'Teich.', 'Ein', 'Frosch', 'Plop.']
"W".isupper()
True

Listen#

Lösen Sie mit einem Einzeiler#

l1: Eine Liste l1 mit allen Zahlen von 0 bis n, hier mit n=5

n = 5
... # 
assert l1 == [0, 1, 2, 3, 4, 5]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[19], line 3
      1 n = 5
      2 # 
----> 3 assert l1 == [0, 1, 2, 3, 4, 5]

NameError: name 'l1' is not defined

l2: Eine Liste l2, die alle Quadratzahlen von l1 enthält

... # 
assert l2 == [0, 1, 4, 9, 16, 25]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[20], line 2
      1 ... # 
----> 2 assert l2 == [0, 1, 4, 9, 16, 25]

NameError: name 'l2' is not defined

Plausibilitätskontrolle: l1 und l2 haben (bei n = 5) die Zahlen 0, 1 und 4 gemeinsam.

l3: Eine Liste l3, die alle Kubikzahlen (“hoch drei”) enthält, das man aus l1 erzeugen kann

... # 
assert l3 == [0, 1, 8, 27, 64, 125]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[21], line 2
      1 ... # 
----> 2 assert l3 == [0, 1, 8, 27, 64, 125]

NameError: name 'l3' is not defined

Plausibilitätskontrolle: l2 und l3 haben (bei n = 5) nur die Zahlen 0 und 1 gemeinsam.

s23: Ein Set s23, das alle Quadrat- und alle Kubikzahlen enthält, das man aus l1 erzeugen kann

  • einfach: mit Benutzung von l2 und l3

  • anspruchsvoller: als Einzeiler nur mit Benutzung von l1

# einfach
... # 
#anspruchsvoller
... # 
assert s23 == {0, 1, 4, 8, 9, 16, 25, 27, 64, 125}
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[22], line 5
      1 # einfach
      2 # 
      3 #anspruchsvoller
      4 # 
----> 5 assert s23 == {0, 1, 4, 8, 9, 16, 25, 27, 64, 125}

NameError: name 's23' is not defined

l2_minus_l3: Eine Liste l2_minus_l3, in der alle Elemente aus l2 enthalten sind, die nicht in l3 enthalten sind.

  • Reihenfolge relevant? Lösung mit List Comprehension!

  • Wenn die Reihenfolge egal ist: Lösung mit Hilfe von Sets!

# Lösung mit List Comprehension
... # 
assert l2_minus_l3 == [4, 9, 16, 25]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[23], line 3
      1 # Lösung mit List Comprehension
      2 # 
----> 3 assert l2_minus_l3 == [4, 9, 16, 25]

NameError: name 'l2_minus_l3' is not defined
# Lösung mit Hilfe von Sets
... # 
assert set(l2_minus_l3) == { 4, 9, 16, 25 }
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[24], line 3
      1 # Lösung mit Hilfe von Sets
      2 # 
----> 3 assert set(l2_minus_l3) == { 4, 9, 16, 25 }

NameError: name 'l2_minus_l3' is not defined

Übertragung Set-Operatoren auf Listen#

Aufgabe hier: Übertragung obiger grundlegenden Mengen-Operatoren auf Listen. Wesentlicher Unterschied:

  • Die Reihenfoge ist relevant.

  • Mehrfach vorkommende ELemente sind erlaubt (und dürfen auch nicht weggeworfen werden) – Zwischenschritte mit Set-Operatoren scheiden also aus.

Terminologie: Statt Schnittmenge reden wir informell von einer Schnittliste etc., die Bedeutung ist offensichtlich.

Und klar: Lösen Sie die Aufgabe mit einem Einzeiler ;-)

l_21 = [3, 2, 1, "a"]
l_22 = [3, "a", "c", "b"]

l_23: Schnitt-Liste von l_21 und l_22: Elemente aus l_21 (mit Reihenfolge), die auch in l_22 enthalten sind

... # 
l_23
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[26], line 2
      1 ... # 
----> 2 l_23

NameError: name 'l_23' is not defined

l_24: Vereinigungs-Liste von l_21 und l_22: Alle Elemente aus l_21, dann alle Elemente aus l_22.

... # 
l_24
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[27], line 2
      1 ... # 
----> 2 l_24

NameError: name 'l_24' is not defined

l_25: Differenz-Liste: alle Elemente aus l_21, die nicht in l_22 enthalten sind

l_25 = [ i for i in l_21 if i not in l_22 ]
l_25
[2, 1]

In eine Funktion packen#

Bereits oben gelöst: Schnittliste, Differenzliste.

Hier zu lösen: Definition entsprechender Funktionen.

Funktion schnittliste(x, y): gibt als Liste alle Elemente zurück, die sowohl in der Liste x wie auch in der Liste y enthalten sind.

def schnittliste(x, y):
    """gibt als Liste alle Elemente zurück, 
    die sowohl in der Liste x wie auch in der Liste y enthalten sind."""
    ... # 
    return ergebnis
assert schnittliste(l_21, l_22) == [3, 'a']
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[30], line 1
----> 1 assert schnittliste(l_21, l_22) == [3, 'a']

Cell In[29], line 5, in schnittliste(x, y)
      2 """gibt als Liste alle Elemente zurück, 
      3 die sowohl in der Liste x wie auch in der Liste y enthalten sind."""
      4 ... # 
----> 5 return ergebnis

NameError: name 'ergebnis' is not defined

Funktion differenz_poly(x, y): gibt alle Elemente aus x zurück, nicht in y enthalten sind.

  • Wenn x ein Set ist, wird auch y wie eine Set behandelt, dann Mengen-Operation

  • Wenn x eine Liste ist, wird auch y wie eine Liste behandelt, dann Listen-Operation

Tip: Es gilt type([1,2,3]) == list; type({1,2,3}) == set

def differenz_poly(x, y):
    if type(x) == set:
        ergebnis =  { i for i in x if i not in y }
    elif type(x) == list:
        ergebnis = [ i for i in x if i not in y ]
    else:
        print(f"ERROR: differenz_poly({type(x)}, {type(y)}) is undefinded")
        ergebnis = None
    return ergebnis
assert differenz_poly(l_21, l_22) == [2, 1]
assert differenz_poly(s1, s2) == {1, 2}
differenz_poly(3, 4)
ERROR: differenz_poly(<class 'int'>, <class 'int'>) is undefinded

Das ist mies!#

Mit den folgenden Ausdrücken versuchen wir Sie zu verwirren. Das ist mies – einerseits. Andererseits müssen Sie gerade mit solchen Ausdrücken zurechtkommen, wenn Sie Denkfehler in Fremdcode und – schwieriger – eigenem Code entdecken wollen.

Sei gegeben string = "abcba".

string = "abcba"

Auswertung bei dieser Aufgabe:

  • 1 Punkt für jede richtige Antwort

  • 1 Punkt Abzug (!) für jede falsche Antwort

  • +-0 Punkte für jede nicht abgegebene Antwort.

Es ist also eine gute Strategie, nur dort eine Antwort zu geben, wo Sie sicher sind.

Was wird bei den folgenden Ausdrücken ausgegeben?

#[ i for i in string]
... # 
#set(string)
... # 
#{ string }
... # 
#str(set(string))
... # 
#string[2]
... # 
#string[2:3]
... # 
#string[::]
... # 
#str()
... # 
#str
... #