Beruflich Dokumente
Kultur Dokumente
g
Einführung in die wissenschaftliche Programmierung
la
Klausur: IN8008 / Endterm Datum: Montag, 19. Februar 2024
Prüfer: Prof. Hans-Joachim Bungartz Uhrzeit: 13:30 – 14:30
ch
A1 A2 A3 A4 A5
I
rs
vo
Bearbeitungshinweise
gs
• Diese Klausur umfasst 12 Seiten mit insgesamt 5 Aufgaben. Bitte kontrollieren Sie jetzt, dass Sie eine
vollständige Angabe erhalten haben.
• Die Gesamtpunktzahl in dieser Klausur beträgt 49 Punkte.
• Es werden nur solche Ergebnisse gewertet, bei denen der Lösungsweg erkennbar ist. Auch Text-
aufgaben sind grundsätzlich zu begründen, sofern es in der jeweiligen Teilaufgabe nicht ausdrücklich
anders vermerkt ist.
Lö
• Schreiben Sie weder mit roter / grüner Farbe noch mit Bleistift.
• Wenn Sie Funktionen aus externen Packages (z.B. NumPy, math) nutzen, importieren Sie diese
explizit.
• Schalten Sie alle mitgeführten elektronischen Geräte vollständig aus, verstauen Sie diese in Ihrer
Tasche und verschließen Sie diese.
– Seite 1 / 12 –
Aufgabe 1 Merging Dictionaries (10 Punkte)
0 Schreiben Sie eine Funktion merge_dictionaries, die zwei Dictionaries auf eine spezielle Art zusammenfügt.
Die Funktion erhält zwei Dictionaries (dict1 und dict2) als Inputargumente und gibt ein neues Dictionary
1 zurück. Das zurückgegebene Dictionary wird aus den anderen beiden mit folgenden Regeln zusammenge-
setzt:
2
• Wir nehmen an, dass beide Inputdictionaries nur Listen oder Integer als Werte haben.
3 • Angenommen ein Key kommt in beiden Inputdictionaries vor und hat eine Liste als Wert in dict1, dann
wird der Wert des entsprechenden Keys in dict2 (Eine Liste oder ein Integer) dieser Liste hinzugefügt.
4 • Angenommen ein Key kommt in beiden Inputdictionaries vor und hat einen Integer als Wert in dict1,
dann wird eine neue Liste erstellt. Der Wert des entsprechenden Keys in dict2 (Eine Liste oder ein
5
Integer) wird dieser Liste hinzugefügt.
g
6 • Angenommen ein Key kommt nur in einem der beiden Inputdictionaries vor. In diesem Fall wird der
Key nicht in das neue Dictionary übernommen.
la
7 Hinweis: Sie können die eingebaute Funktion isinstance benutze, um die Typen einer Variablen zu teten.
Beispielsweise isinstance([1,2], list) −→ True oder isinstance(4.0, int) −→ False
8 Beispiel zu merge_dictionaries:
9 # First dictionary
ch
dict1 = { 'a ' : 1 , 'b ' : [2 , 3] , ' c ' : 4 , 'e ' : 8 , ' f ' : [11 , 12]}
10
# Second d i c t i o n a r y
d i c t 2 = { ' b ' : [ 4 , 5 ] , ' c ' : 6 , ' d ' : 7 , ' e ' : [ 9 , 1 0 ] , ' f ' : 13}
# The r e s u l t should be :
result = { 'b ' : [2 , 3 , [4 , 5]] , ' c ' : [4 , 6] , 'e ' : [8 , [9 , 10]] ,\
' f ' : [ 1 1 , 12 , 1 3 ] }
# F u n c t i o n t o merge d i c t i o n a r i e s
rs
vo
def m e r g e _ d i c t i o n a r i e s ( d1 , d2 ) :
merged_dict = d i c t ( ) # o r { }
i f i s i n s t a n c e ( d1 [ key ] , l i s t ) :
v a l u e . append ( d2 [ key ] )
merged_dict [ key ] = v a l u e
e l i f i s i n s t a n c e ( value , i n t ) :
merged_dict [ key ] = [ value , d2 [ key ] ]
n
# Merge d i c t i o n a r i e s by c a l l i n g t h e f u n c t i o n
su
• 1pt - Checking for common keys / Checking if the key (doesn’t) occurs in a dictionary
• 2pt - for if-else statement that handles the different cases of the values in the first dictionary
• 1pt - Appending the value from the second dictionary to the first; Proper usage of the append function; -0.5pt
• 1pt - Properly handling the case when the first value is an int and created a list
• 0.5pt - Proper return statement
• 1pt - Correctly calling the function and handling execution / Propagation of the return arguments and capturing the return statement
• Total = 10pts
– Seite 2 / 12 –
Aufgabe 2 Die ISBN: Strings und Listen (15 Punkte)
In dieser Aufgabe geht es um die Internationale Standardbuchnummer, besser bekannt als ISBN. Die ISBN
ist eine international Eindeutige Kennung für Bücher und andere Medien.
Hinweis: Für einige Teilaufgaben ist es hilfreich, die Funktionen aus vorherigen Teilaufgaben zu verwenden.
g
und Bindestriche entfernt wurden.
la
Für die obigen Beispiele sollte die Funktion als folgende Ergebnisse liefern:
• 3-540-09853-4 → 3540098534
• 3 540 09853 4 → 3540098534
• 038750334X → 038750334X
ch
Hinweis: Schreiben sie das Leerzeichen in Ihrem Code explizit als t.
def c l e a n ( s ) :
s = s . replace ( " " , " " )
s = s . replace ( "−" , " " )
return s
# Aternative Solution
def c l e a n _ a l t e r n a t i v e ( s ) :
rs
vo
s_new = " "
for c in s :
i f c not i n [ " " , " − " ] :
s_new += c
r e t u r n s_new
gs
Punkte:
• Korrekte Funktionsdefinition (0.5)
• Entfernen von Bindestrichen und Leerzeichen (1)
• return statement (0.5)
n
b) Eine ISBN-10 besteht aus 10 Zeichen. Die ersten neun Zeichen sind Ziffern. Das letzte Zeichen kann 0
zudem X (großes X) sein.
su
Nutzen Sie reguläre Ausdrücke, um eine Funktion check_format zu schreiben. Diese bekommt einen String 1
übergeben und gibt als Boolean zurück, ob der übergebene String eine ISBN-10 ist.
2
3
import r e
Lö
def check_format ( s ) :
s = clean ( s )
r e t u r n bool ( r e . match ( r " \ d { 9 } [ \ dX ] ? " , s ) )
Punkte:
• import re (0.5)
• Verwendung von clean (0.5)
• Korrekte Verwendung von re.match (0.5)
• Regex für ISBN-10 (1)
• Korrekte Rückgabe (0.5)
– Seite 3 / 12 –
0 c) Um Fehler zu erkennen verfügen ISBNs über eine eingebaute Fehlererkennung. Um diese nutzen zu
können muss die ISBN in eine Integerliste umgewandelt werden. Hierbei zählt X als 10. Schreiben Sie eine
1 Funktion to_list, einen String erhält und diese Umwandlung vornimmt. Die daraus resultierende Liste soll
zurückgegeben werden. Nehmen Sie an, dass der übergebene String eine ISBN-10 ist.
2
3
def t o _ l i s t ( s ) :
4 s = clean ( s )
output = [ ]
for c in s :
i f c ! = "X" :
o u t p u t . append ( i n t ( c ) )
g
else :
o u t p u t . append ( 1 0 )
return output
la
Punkte:
• Nutzung von clean (0.5)
• Listeninitialisierung (0.5)
ch
• for-loop über String (0.5)
• Korrekte Logik für X (1)
• Listenerweiterung (0.5)
• String zu Integer (0.5)
• return (0.5)
rs
vo
0 d) Eine ISBN-10 ist korrekt, wenn folgende Gleichung erfüllt ist:
9
!
1 X
(i + 1)zi mod 11 = 0,
2 i=0
gs
3 wobei zi die ISBN-Ziffer an der Stelle i ist und X als 10 gewertet wird. Schreiben Sie eine Funktion validate,
die einen String erhält. Nutzen Sie List Comprehension und die eingebaute Funktion sum, um zu überprüfen,
ob die ISBN-10 korrekt ist und lassen sie die Funktion den entprechenden Wahrheitswert zurückgeben.
Hinweis: sum nimmt eine Liste als Argument und gibt die Summe über alle Listenelemente zurück.
n
def v a l i d a t e ( s ) :
isbn_list = to_list (s)
su
Punkte:
• Nutzung von to_list (0.5)
Lö
– Seite 4 / 12 –
e) Wir wollen nun für einen gegeben String testen, ob er eine valide ISBN-10 ist. Schreiben Sie dazu eine 0
Funktion test_ISBN, die den String übergeben bekommt. Hat dieser String das falsche Format, soll ein
ValueError ausgeworfen werden. Ist stattdessen die ISBN-10 nicht gültig, soll ein AssertionError ausgege- 1
ben werden. In beiden Fällen soll eine hilfreiche Fehlermeldung erzeugt werden. Ist die ISBN-10 gültig, soll
2
nichts passieren.
def test_ISBN ( s ) :
i f not check_format ( s ) :
r a i s e V a l u e E r r o r ( s + " i s n o t i n ISBN−10 f o r m a t ! " )
i f not v a l i d a t e ( s )
g
r a i s e A s s e r t i o n E r r o r ( s + " i s n o t a v a l i d ISBN −10! " )
Punkte:
la
• Korrekte Logik (Format vor Validate) (0.5)
• Korrekte Logik ifs und Nutzung vorheriger Fkts. (0.5)
• raise ValueError(0.5)
• raise AssertionError (0.5)
ch
• Fehlermeldung (0.5)
rs
vo
n gs
su
Lö
– Seite 5 / 12 –
Aufgabe 3 Objektorientierte Programmierung (12 Punkte)
In dieser Aufgaben geht es um die Fußball-Europameisterschaft im Sommer 2024 in Deutschland. Daran
werden 24 Nationen teilnehmen, und es werden 51 Spiele ausgetragen werden.
class Team :
g
a n z a h l S p i e l e r = 23
def _ _ i n i t _ _ ( s e l f , n a t i o n ) :
la
s e l f . __nation = nation
Punkte:
• Klassendefinition syntaktisch korrekt (0.5)
ch
• Klassenvariable da + korrekt initialisiert (0.5)
• Konstruktor: Parameter + self da (0.5)
• Konstruktor: Objektvariable korrekte Syntax + Wert (0.5+0.5)
0
rs
b) Geben Sie den nötigen Python-Code an, um die Klasse aus Teilaufgabe a) um eine Methode getNation()
vo
zu erweitern, welche die private Objektvariable zurückgibt!
1
def g e t N a t i o n ( s e l f ) :
return s e l f . __nation
gs
Punkte:
• Syntax korrekt: self da und richtig benutzt (0.5)
• return syntaktisch und semantisch korrekt (0.5)
n
c) Schreiben Sie eine Klassenmethode getAnzahlSpieler() für die Klasse Team aus Teilaufgabe a), die die
su
0
Klassenvariable anzahlSpieler zurückgibt!
1
@classmethod
def g e t A n z a h l S p i e l e r ( c l s ) :
Lö
r e t u r n Team . a n z a h l S p i e l e r # c l s . a n z a h l S p i e l e r a l s o ok
Punkte:
• Schlüsselwort \@classmethod da und richtig benutzt (0.5)
• Schlüsselwort cls da und richtig benutzt (0.5)
• Zugriff auf Klassenvariable syntaktisch (0.5)
– Seite 6 / 12 –
d) Schreiben Sie eine Klasse Spiel, 0
• die im Konstruktor die Parameter stadion, team1, und team2 übergeben bekommt und dort zugehörige
Objektvariablen definiert; 1
• die im Konstruktor eine Objektvariable id mit Null initialisiert;
2
• die eine Methode setID() enthält, die die zugehörige Objektvariable auf einen Wert setzt, der als
Parameter übergeben wird.
class S p i e l :
def _ _ i n i t _ _ ( s e l f , s t a d i o n , team1 , team2 ) :
s e l f . __id = 0
s e l f . stadion = stadion
g
s e l f . team1 = team1
s e l f . team2 = team2
def s e t I D ( s e l f , n r ) :
la
s e l f . __id = nr
Punkte:
• Konstruktor: alle 3 Parameter + self da (0.5)
ch
• Konstruktor: Objektvariablen korrekte Syntax + Werte (inkl. Null) (0.5+0.5)
• Methode setID(): self + Parameter korrekt (0.5)
rs
vo
e) Schreiben Sie eine Klassenmethode liste_infos() für die Klasse Spiel aus Teilaufgabe d), die alle 0
Objektvariablen auf die Kommandozeile ausgibt. Stellen Sie sicher, dass für die beiden Mannschaften die
Methode getNation() benutzt wird, um die zugehörige Information zu erhalten. 1
gs
Bezeichnung “Klassenmethode” nicht sauber. gemeint war “Methode”, daher großz. Korrektur
def l i s t e _ i n f o s ( s e l f ) :
p r i n t ( " S p i e l m i t Nr . " , s e l f . __id , " im S t a d i o n " , s e l f . s t a d i o n , " : " ,
n
Punkte:
su
– Seite 7 / 12 –
0 f) Implementieren Sie eine Klasse Gruppenspiel,
• die von Spiel aus Teilaufgabe d) erbt;
1 • die im Konstruktor zusätzlich zu den Parametern für den Basisklassenkonstruktor noch einen Parameter
gruppe übergeben bekommt und diese zugehörigen Objektvariablen zuweist;
2
• die den Konstruktor der Basisklasse aufruft.
class Gruppenspiel ( S p i e l ) :
def _ _ i n i t _ _ ( s e l f , s t a d i o n , team1 , team2 , gruppe ) :
S p i e l . _ _ i n i t _ _ ( s e l f , s t a d i o n , team1 , team2 )
s e l f . gruppe = gruppe
Punkte:
g
• Vererbung syntaktisch korrekt (0.5)
• Aufruf von Basisklassenkonstruktor korrekt (0.5) und mit richtigen 3 Parametern + self (0.5)
la
• Objektvariablen korrekte Syntax + Werte (0.5)
ch
0 g) Geben Sie den Python-Code an,
2
land” und “Schottland”;
rs
• um je ein Objekt vom Klassentyp Team aus Teilaufgabe a) zu instantiieren, mit den Nationen “Deutsch-
Punkte:
• team1,2 korrekt (Konstruktor etc. 0.5)
• Aufruf von setID() korrekt (0.5)
• korrekter Zugriff auf Klassenmethode (0.5) und print passend (0.5)
n
su
Lö
– Seite 8 / 12 –
Aufgabe 4 NumPy Arrays und Pandas (7 Punkte)
a) Schreiben Sie einen Code, um einen eindimensionalen NumPy-Array zu erstellen, das die Werte 1 bis 10 0
in korrekter Reigenfolge enthält.
1
import numpy as np
# myarray = np . a r r a y ( range ( 1 , 1 1 ) ) # v a l i d
myarray = np . arange ( 1 , 1 1 )
# myarray = np . a r r a y ( [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 1 0 ] ) # s t i l l 1 pt , f o r being c r e a t i v e : − )
g
Punkte:
la
• 0.5: for import
• 1pt for constructing the array; -0.5 if using both wrong boundaries, e.g., range(,10); still 1pt for messing up one boundary range(1,10),
range(1,11)
ch
b) Wir wollen nun alle Werte in einem NumPy-Array finden, die größer als eine gewisse Grenze sind. Alle 0
ensprechenden Werte sollen durch einen neuen Wert ersetzt werden. Nutzen sie den Array aus a) und filtern
Sie alle Werte größer 5 aus. Diese Werte sollen durch −1 ersetzt werden. 1
t h r e s h o l d = 5 # Threshold v a l u e
rs
Hinweis: Sie können entweder einen neuen Array erstellen oder den obigen modifizieren.
2
vo
new_value = −1 # New v a l u e t o r e p l a c e elements t h a t meet t h e c o n d i t i o n
f i l t e r e d _ a r r a y = myarray
# Var2 : Use where f u n c t i o n t o f i l t e r and r e p l a c e elements
f i l t e r e d _ a r r a y = np . where ( myarray > t h r e s h o l d , new_value , myarray )
Punkte:
n
• 2pt
su
Lö
– Seite 9 / 12 –
0 c) Wie kann der obige Array in einem Pandas DataFrame gespeichert werden, das lediglich eine Spalte
hat? Schreiben Sie ihre Antwort als Code.
1
import pandas as pd
d f = pd . DataFrame ( myarray , columns = [ ' data ' ] )
Punkte:
g
0 d) Wie könnten Sie die Werte in einem Pandas DataFrame mit einer einzelnen Zeile Code wie in b) filtern
la
und ersetzen.
1 Hinweis: Sie können entweder ein neues DataFrame erstellen oder das obige modifizieren.
2
ch
d f . l o c [ d f [ ' data ' ] > t h r e s h o l d ] = new_value # accept as w e l l d f . l o c [ d f > t h r e s h o l d ] =
# d f = d f . mask ( d f > t h r e s h o l d , new_value ) # y e t a n o t h e r example , u s i n g mask
Punkte:
• 2pt
rs
vo
n gs
su
Lö
– Seite 10 / 12 –
Aufgabe 5 Übungsbonus (5 Punkte)
Diese Aufgabe ist lediglich dazu da, damit wir einen möglichen Übungsbonus, einfach einberechnen können. 0
Nutzen Sie diese Seite NICHT für Notizen! Alles, was auf dieser Seite steht wird nicht bewertet!
1
g
la
ch
rs
vo
n gs
su
Lö
– Seite 11 / 12 –
Zusätzlicher Platz für Lösungen. Markieren Sie deutlich die Zuordnung zur jeweiligen Teilaufgabe.
Vergessen Sie nicht, ungültige Lösungen zu streichen.
g
la
ch
rs
vo
n gs
su
Lö
– Seite 12 / 12 –