Sie sind auf Seite 1von 18

Klausur 19.

Februar 2019

Informatik 1
Einführung in die Programmierung
WS 2018
Prof. Dr. Peter Thiemann
Institut für Informatik
Albert-Ludwigs-Universität Freiburg

Name:

RZ-LOGIN:

• Bitte schreiben Sie Ihren Namen auf jedes Blatt.


• Es sind keine Hilfsmittel wie Skripte, Bücher, Notizen oder Taschenrechner er-
laubt. Desweiteren sind alle elektronischen Geräte (wie z.B. Handys) auszuschal-
ten.
• Für die Bearbeitung der Aufgaben haben Sie 120 Minuten Zeit.
• Benutzen Sie zur Bearbeitung der Aufgaben jeweils den Platz unterhalb der Auf-
gaben sowie ggf. den Platz auf den beigefügten leeren Seiten.
• Falls Sie mehrere Lösungsansätze einer Aufgabe erarbeiten, markieren Sie deutlich,
welcher gewertet werden soll.

Erreichbare Punkte Erzielte Punkte Nicht bearbeitet


Aufgabe 1 20
Aufgabe 2 12
Aufgabe 3 10
Aufgabe 4 16
Aufgabe 5 16
Aufgabe 6 18
Aufgabe 7 16
Aufgabe 8 12
Gesamt 120
Info 1 Klausur WS 2018

Aufgabe 1 (Python-Shell; Punkte: 4+4+4+4+4).


Welche Ausgaben erhalten Sie in der Python-Shell bei Eingabe der folgenden Befehle?

(a) >>> g = ((x, y) for x in range(1, 10)


... for y in range(2, 10) if x % y == 0 and x != y)
...
>>> next(g), next(g)

(b) >>> def f(x):


... return lambda y: [x, x + y]
...
>>> d = dict((x, f(x)) for x in range(10))
>>> d[4](6)[1], f(17)(4)

(c) >>> (lambda x, y: y(x))("hi", lambda x: x * 3)

(d) >>> try:


... {1: 2, 2: 4, 3: 9}[3]
... except KeyError:
... print("foo")
... finally:
... print("bar")
...

(e) >>> for i in range(1, 6):


... print(("Fizz" * (i % 3 == 0) + "Buzz" * (i % 5 == 0)) or str(i))
...
Info 1 Klausur WS 2018 Name:
Info 1 Klausur WS 2018

Aufgabe 2 (Wissen; Punkte: 2+2+2+2+4).


Kreuzen Sie im folgenden jeweils ausschließlich die richtige(n) Antwort(en) an. Falsche
Kreuze führen zu einer 0-Punkte-Bewertung der jeweiligen Teilaufgabe.
(a) Die Post-Order-Traversierung eines Suchbaums gibt dessen Knotenmarkierungen

 aufsteigend sortiert aus.


 absteigend sortiert aus.
 weder absteigend noch aufsteigend sortiert aus.

(b) Wird der Rumpf eines Generators mit return beendet, so wird

 der Wert nach dem return-Statement zurückgegeben.


 immer None zurückgegeben.
 eine DontStopMeNow-Ausnahme ausgelöst.
 eine StopIteration-Ausnahme ausgelöst.

(c) Iteratoren

 generalisieren Generatoren.
 implementieren das Iteratorprotokoll.
 können an allen Stellen stehen, an denen ein iterierbares Objekt stehen kann
(z.B. for-Schleifen).
 liefern ein iterierbares Objekt beim Aufruf von iter().

(d) Unterklassen

 erben Attribute und Methoden von der Oberklasse


 können neue Attribute und Methoden einführen
 können Attribute und Methoden der Oberklasse überschreiben
 können überschriebene Methoden der Oberklasse aufrufen
Info 1 Klausur WS 2018 Name:

(e) Geben Sie die Knotenmarkierungen des folgenden Binärbaums in der Reihenfolge
einer In-order Traversierung an:

3 6

1 2 4 5

Antwort:
Info 1 Klausur WS 2018

Aufgabe 3 (Ausdrucksbäume; 10 Punkte).


Boolesche Ausdrücke lassen sich wie arithmetische Ausdrücke durch Bäume repräsentieren.
Hierbei enthalten die inneren Knoten boolesche Operatoren (wir repräsentieren diese
als Strings 'AND', 'OR' und 'NOT'). Die Blätter enthalten boolesche Variablen (be-
liebige andere Strings). Diese können die Wahrheitswerte True und False annehmen.
Betrachten Sie dazu zunächst die folgenden drei Beispiele, wobei Op und Proposition
wie auf der folgenden Seite definiert sind:

t1 = Proposition('p') t2 = Op('AND', [ t3 = Op('OR', [


t1, Proposition('q'),
Proposition('q')]) Op('NOT', [
Proposition('q')])])

Ausdrucksbaum: Ausdrucksbaum: Ausdrucksbaum:

p and or

p q q not

Ausdruck: p Ausdruck: p and q Ausdruck: q or (not q)

(a) Implementieren Sie die Methode Op.evaluate(v), welche für eine gegebene Va-
riablenbelegung v den repräsentierten Boolschen Ausdruck auswertet und den
resultierenden Wahrheitswert zurückgibt. Die Variablenbelegung v ist dabei ein
Dictionary, welches jeder in t vorkommenden Variablen entweder True oder
False zuordnet. Gehen Sie davon aus, dass jeder Baum einen wohlge-
formten boolschen Ausdruck repräsentiert, also ein NOT-Knoten immer
genau ein Kind hat, AND und OR-Knoten jeweils genau zwei Kinderkno-
ten haben und alle Blattknoten Propositionen sind. Beispiel:

>>> v = {'p': True, 'q': False}


>>> t1.evaluate(v), t2.evaluate(v), t3.evaluate(v)
(True, False, True)
Info 1 Klausur WS 2018 Name:

class Formula:
pass

class Proposition(Formula):
def __init__(self, name):
self.name = name

def evaluate(self, v):


return v.get(self.name, False)

class Op(Formula):
def __init__(self, name, children: list):
self.name = name
self.children = children

def evaluate(self, v):


if self.name == 'NOT':
# TODO: fill in

elif self.name == 'AND':


# TODO: fill in

elif self.name == 'OR':


# TODO: fill in

else:
raise Exception("Tree not well-formed")
Info 1 Klausur WS 2018

Aufgabe 4 (Fehler; Punkte: 12+4).


Die Funktion count(ls: list) -> dict soll, für jedes Element einer Eingabeliste,
die Häufigkeit mit der das Element in der Eingabeliste vorkommt, bestimmen und ein
Dictionary zurückgeben, welches jedem Element der Eingabeliste die entsprechende
Häufigkeit als Wert zuweist. Beispiel:

>>> count([1, 2, 1, 1, 'eggs', 2])


{1: 3, 2: 2, 'eggs': 1}

Die folgende Implementierung von count enthält (mindestens) drei Fehler:

1 def count(ls: list) -> dict


2 res = {}
3 for item in ls:
4 if item not in res:
5 res[item] = 0
6 res[item] += 1
7 return res

(a) Finden Sie die Fehler und tragen Sie, für jeden Fehler, die Zeile in welche der
Fehler im Programmcode auftritt, den Fehlertyp (Semantik-, Laufzeit- oder Syn-
taxfehler), sowie eine kurze Erläuterung, in die untenstehende Tabelle ein.

Zeile Fehlertyp Beschreibung

(b) Geben Sie, für jeden Semantik- oder Laufzeitfehler, einen geeigneten Testfall, be-
stehend aus Eingabeliste und erwartetem Rückgabewert, an. Die Testfälle sollten
im nicht-korrigierten Code zu einem Fehler des entsprechenden Typs führen.
Eingabeliste (ls) Erwarteter Rückgabewert
Info 1 Klausur WS 2018 Name:
Info 1 Klausur WS 2018

Aufgabe 5 (Rekursion, Endrekursion; Punkte: 8+8).

(a) Implementieren Sie eine iterative Version der folgenden endrekursiven Funktion:

def gcd(x: int, y: int) -> int:


if y == 0:
return x
return gcd(y, x % y)

(b) Die Funktionen


• p(n: int) -> bool
• q(n: int) -> bool
• foo(n: int) -> int
• bar(n: int) -> int
• quux(n: int) -> int
sind entsprechend ihrer Signatur definiert. Implementieren Sie eine endrekursive
Variante der folgenden iterativen Funktion:

def xxx(n: int) -> int:


while p(n):
if q(n):
n = foo(n)
else:
n = bar(n)
return quux(n)
Info 1 Klausur WS 2018 Name:

def gcd( ) -> int:


# Your code here

def xxx( ) -> int:


# Your code here
Info 1 Klausur WS 2018

Aufgabe 6 (Generatoren; 6+6+6 Punkte).


Achtung: Verwenden Sie zur Bearbeitung dieser Aufgabe keine zusätzlichen
Module, insbesondere nicht das Modul itertools.
(a) Ergänzen Sie die Generator-Funktion chain. Sie soll als Eingabe eine Liste von
iterierbaren Objekten nehmen und einen Generator implementieren, der die Ele-
mente dieser Objekte der Reihe nach aufzählt.

>>> tuple(chain(['Foo', ['Ba', 'r']]))


('F', 'o', 'o', 'Ba', 'r')

(b) Ergänzen Sie die Generator-Funktion accumulate, welche einen Iterator erzeugt,
der die akkumulierten Summen der Elemente eines iterierbaren Objektes iterable
zurückgibt. Beispiel:

>>> tuple(accumulate([1, 2, 3, 4]))


(1, 3, 6, 10)

(c) Ergänzen Sie die Generator-Funktion cycle, welche einen Iterator erzeugt, der
Elemente aus einem iterierbaren Objekt zurückgibt und von jedem zurückgegebenem
Element eine Kopie speichert. Wenn das iterierbare Objekt erschöpft ist, werden
wiederholt die Elemente aus der gespeicherten Kopie zurückgegeben.

>>> hi = cycle('Hi')
>>> for v in range(5):
... print(next(hi))
...
H
i
H
i
H
Info 1 Klausur WS 2018 Name:

def chain(iterables: list):


# chain(['ABC', 'DEF']) --> A B C D E F

def accumulate(iterable):
# accumulate([1, 2, 3, 4]) --> 1 3 6 10

def cycle(iterable):
# cycle("Hi") --> H i H i H ...
Info 1 Klausur WS 2018

Aufgabe 7 (Funktionale Programmierung; Punkte: 6+4+6).

(a) Welche Ausgabe erhalten Sie in der Python-Shell bei Eingabe der folgenden Be-
fehle?

>>> spam = "sausage"


>>> def test():
... def foo():
... spam = "bacon"
... def bar():
... nonlocal spam
... spam = "spam"
... def baz():
... global spam
... spam = "ham"
... spam = "eggs"
... foo()
... print(spam)
... bar()
... print(spam)
... baz()
... print(spam)
...
>>> test()
>>> print(spam)

(b) Erstellen Sie, mit Hilfe einer List-Comprehension, eine Liste hs der ersten 100
Glieder der Harmonischen Folge. Die Harmonische Folge ist die mathematische
Zahlenfolge der Kehrwerte der positiven ganzen Zahlen, also die Folge
1 1 1 1
1, , , , , ...
2 3 4 5

>>> hs = [ ]
Info 1 Klausur WS 2018 Name:

(c) Schreiben Sie eine Funktion compose(f, g), welche zwei einstellige Funktionen
f(x: int) -> int und g(x: int) -> int als Argumente übergeben bekommt
und eine neue Funktion zurückgibt, welche die Hintereinanderausführung von f
und g implementiert, sodass für alle x ∈ N: compose(f, g)(x) == f(g(x)).
Beispiel:

>>> compose(lambda x: x + 35, lambda x: x * 2)(5)


45

def compose(f, g):


"""Returns the composition of f and g."""
Info 1 Klausur WS 2018

Aufgabe 8 (Brainfuck; Punkte: 6+6).

(a) Welche Ausgabe erzeugt ein Brainfuck-Interpreter bei Ausführung der folgenden
Befehlssequenz?

+egg+++++[>++++++++++<-]>++++++.

(b) Schreiben Sie ein Brainfuck-Programm, welches den Wert einer gegebenen Zelle
negiert. Wir verstehen jeden Wert ungleich 0 als True und den Wert 0 als False.
Ist der Wert der aktuellen Zelle ungleich 0, so soll der Wert der rechten Nach-
barzelle auf 0 gesetzt werden, ist der Wert gleich 0, so soll die Nachbarzelle auf
einen Wert ungleich 0 gesetzt werden. Ihr Lösungsvorschlag muss weniger als 20
Zeichen lang sein.
Info 1 Klausur WS 2018 Name:

Short: 240 byte compiler. Fun, with src. OS 2.0


Uploader: umueller amiga physik unizh ch
Type: dev/lang
Architecture: m68k-amigaos

The brainfuck compiler knows the following instructions:

Cmd Effect
--- ------
+ Increases element under pointer
- Decrases element under pointer
> Increases pointer
< Decreases pointer
[ Starts loop, flag under pointer
] Indicates end of loop
. Outputs ASCII code under pointer
, Reads char and stores ASCII under ptr

Who can program anything useful with it? :)

Abbildung 1: Brainfuck Semantik von 1993.

Dez Hex Okt Zeichen Dez Hex Okt Zeichen


65 0x41 101 A 97 0x61 141 a
66 0x42 102 B 98 0x62 142 b
67 0x43 103 C 99 0x63 143 c
68 0x44 104 D 100 0x64 144 d
69 0x45 105 E 101 0x65 145 e

.. .. .. .. .. .. .. ..
. . . . . . . .

88 0x58 130 X 120 0x78 170 x


89 0x59 131 Y 121 0x79 171 y
90 0x5A 132 Z 122 0x7A 172 z

Abbildung 2: Ausschnitt einer ASCII-Tabelle.


Info 1 Klausur WS 2018 Name:

Das könnte Ihnen auch gefallen