Sie sind auf Seite 1von 12

Chair of Scientific Computing in Computer Science

School of Computation, Information and Technology


Technische Universität München

Hinweise zur Personalisierung:


• Ihre Prüfung wird bei der Anwesenheitskontrolle durch Aufkleben eines Codes persona-
Esolution lisiert.
• Dieser enthält lediglich eine fortlaufende Nummer, welche auch auf der Anwesenheits-
Sticker mit SRID hier einkleben
liste neben dem Unterschriftenfeld vermerkt ist.
• Diese wird als Pseudonym verwendet, um eine eindeutige Zuordnung Ihrer Prüfung zu
ermöglichen.

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.

• Das Heraustrennen von Seiten aus der Prüfung ist untersagt.


n

• Als Hilfsmittel sind zugelassen:


su

– ein handbeschriebenes DIN-A4-Blatt


– ein analoges Wörterbuch Deutsch ↔ Muttersprache ohne Anmerkungen

• 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.

• 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.

Hörsaal verlassen von bis / Vorzeitige Abgabe um

– 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 { }

# Other o p t i o n s ( 1 ) i f d2 . g e t ( key ) i s n o t None : ( 2 ) i f key i n d2 . keys ( ) :


i f key i n d2 :
gs

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

merged_dict = m e r g e _ d i c t i o n a r i e s ( d i c t 1 . copy ( ) , d i c t 2 . copy ( ) )


Punkte
• 1pt - Defining the function
• 0.5pt - Initializing an empty dictionary / Or returning a dictionary in some other way...
• 1pt - Iterating through dictionary elements
• 1pt - Correctly accessing the values form the dictionaries, 0.5pt per dictionary

• 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

# 1 p t − Appending t h e v a l u e from t h e second d i c t i o n a r y t o t h e f i r s t ; Proper usage o f t h e append f u n c t i o n ;

• 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.

a) ISBNs existieren in verschiedenen Formatierungen: 0


• mit Bindestrichen, z.B. 3-540-09853-4;
• mit Leerzeichen, z.B. 3 540 09853 4; 1
• oder ohne Trennzeichen, z.B. 038750334X.;
2
Um ISBNs weiter zu verarbeiten müssen wir sie in ein einheitliches Format bringen. Schreiben Sie eine
Funktion clean, die einen String als Argument erhält und einen String zurückgibt, bei dem alle Leerzeichen

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

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

s u m _ r e s u l t = sum ( [ ( i +1) * i s b n _ l i s t [ i ] f o r i i n range ( len ( i s b n _ l i s t ) ) ] )


c h e c k _ r e s u l t = s u m _ r e s u l t % 11
r e t u r n c h e c k _ r e s u l t == 0

Punkte:
• Nutzung von to_list (0.5)

• List Comprehension (1)


• sum (0.5)
• Korrekte Rechnung in LC (0.5)
• Modulo (0.5)
• return statement (0.5)

– 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

– 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.

0 a) Schreiben Sie eine Klasse Team,


• die eine Klassenvariable anzahlSpieler besitzt, die zu Beginn den Wert 23 trägt (Anzahl erlaubter
1 Spieler im Aufgebot jeder Mannschaft);
• die im Konstruktor den Parameter nation übergeben bekommt und dort eine zugehörige private
2
Objektvariable definiert.

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 ) :

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

s e l f . team1 . g e t N a t i o n ( ) , " vs . " , s e l f . team2 . g e t N a t i o n ( ) )

Punkte:
su

• alle 4 Variablen da/benutzt (0.5)


• richtiger Erhalt von Nation-Info über getter (0.5)

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

• um die Anzahl Spieler im Aufgebot einer Nation auszugeben;


• um für ein Objekt game vom Klassentyp Gruppenspiel die ID auf eins zu setzen.
vo
p r i n t ( f ' Jedes Team h a t { Team . g e t A n z a h l S p i e l e r ( ) } S p i e l e r ' )
team1 = Team ( " Deutschland " )
team2 = Team ( " S c h o t t l a n d " )
game . s e t I D ( 1 )
gs

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

– 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

# Var1 : Create a boolean a r r a y where True i n d i c a t e s t h e c o n d i t i o n i s met


c o n d i t i o n = myarray > t h r e s h o l d
myarray [ c o n d i t i o n ] = new_value
gs

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

– 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:

• 0.5: for import

• 1pt for constructing the DF

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

– 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

– 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

– Seite 12 / 12 –

Das könnte Ihnen auch gefallen