Sie sind auf Seite 1von 45

Prüfungsvorbereitung MOS103_Informatik_I

1. Was bedeutet Informatik für Ihr Studium (01_Einführung)?


Die Informatik ist das wichtigste Fach Ihres Studiums! Diese Aussage ist vermutlich
wahr, aber wird diese Wahrheit auch umgesetzt?

2. Vermitteltes Wissen gem. Modulbeschreibung (01_Einführung)


Grundlagen der Informatik, z.B. Datentypen, Kontrollstrukturen, Funktionen und OOP
sind vertraut. Struktur von Programmen kann visualisiert. Lebenszyklus einer
Software von Konzeption und Entwicklung über Betrieb und Wartung ist vertraut.
Probleme können strukturiert, graphisch aufbereitet und Lösungsansätze definiert
werden. Einfache Probleme der Informatik können mit Python selbst gelöst werden.

3. Beschreiben Sie den Lebenszyklus einer Software (01_Einführung)

➢ Forschung & Entwicklung


➢ Produktion
➢ Vertrieb
➢ Betrieb & Wartung
➢ Lebensende & Recycling
➢ Forschung & Entwicklung

4. Was charakterisiert Python (01_Einführung)?

Inspiriert von Monty Python, Guido von Rossum, Interpreter, Multi-Paradigmen,


dynamisch-typisiert

5. Was unterscheidet einen Interpreter von einem Compiler (01_Einführung)?

Programmiersprachen sind so aufgebaut, dass Menschen sie relativ mühelos lesen


und anwenden können. Damit ein Prozessor die einzelnen Anweisungen eines
Programms verstehen kann, muss der Quellcode jedoch erst in eine für die Maschine
verständliche Form gebracht werden. Ein Interpreter verarbeitet den Quellcode eines
Projekts zur Laufzeit. Dazu geht der Interpreter Zeile für Zeile vor: Eine Anweisung
wird eingelesen, analysiert und sofort ausgeführt. Dann geht es mit der nächsten
Anweisung weiter, bis schließlich das Ende des Programms erreicht ist; oder bis ein
Fehler auftritt – der Interpreter stoppt seine Arbeit, sobald etwas nicht stimmt. Ein
Interpreter erzeugt keine Datei, die man mehrmals ausführen könnte. Er fertigt auch
keine Übersetzung des Quellcodes in Maschinensprache um, sondern fungiert als
eine Zwischenschicht zwischen Programmiersprache und Maschine. Python, Perl
oder BASIC sind Beispiele für Sprachen, die einen Interpreter verwenden. Ein
Compiler wandelt Quellcode in Maschinensprache um, übersetzt also das gesamte
Programm von einer Programmiersprache in Maschinencode. Der Code wird
vollständig übersetzt, bevor das Programm ausgeführt wird. Häufig passiert noch ein
Zwischenschritt, bevor das Programm in Maschinensprache übersetzt wird: Der
Quellcode wird zunächst in einen Zwischencode umgewandelt, zum Beispiel
Objektcode. Schließlich wird per Linker eine ausführbare Datei generiert. Der

1
Prüfungsvorbereitung MOS103_Informatik_I

Compiler stößt also mehrere Schritte an, um aus dem vorliegenden Quellcode ein
lauffähiges Programm zu erstellen. Dafür benötigt er vergleichsweise mehr Zeit und
Ressourcen. Sobald das fertige Programm läuft, ist es jedoch effizienter als
interpretierte Software, da alle Anweisungen bereits vollständig in Maschinencode
übersetzt wurden. Reine Compiler-Sprachen sind zum Beispiel C / C++ und Pascal.
Es gibt auch Ansätze, die Compiler und Interpreter vereinen und so die Schwächen
der jeweiligen Systeme ausgleichen. Der Compreter oder Just-in-time-Compiler
übersetzt das Programm erst zur Laufzeit in Maschinencode. Einerseits bietet die
Hybridlösung gute Performance kompilierter Programme, andererseits ermöglicht sie
die komfortable Fehlersuche interpretierter Programme. JIT-Compiler kommen vor
allem beim Erstellen plattformunabhängiger und portabler Software zum Einsatz.
Beispiele für Programmiersprachen mit JIT-Compiler sind Java, Visual Basic, C# und
auch C++.

6. Modulo in Python (01_Übung)

% (a mod b funktioniert nicht!)

7. Potenzieren in Python (01_ Übung)

** (3**4=81, ^ funktioniert nicht)

8. XOR in Python (Einschub)

^ ist die XOR Funktion, 3^8=11 (0011 XOR 0100), 3^10=9 (0011 XOR 1010)

9. Integer-Division in Python (01_ Übung)

// (3/2=1.5, 3//2=1)

10. Import von Modulen in Python (01_ Übung)

Vollständige Libraries: import cmath, import graphics…

Teile von Libraries: from math import pi, from math import e, …(sin, cos, tan..)

11. Printanweisung in Python (01_ Übung)

➢ anzahl_kreuzer = 2
➢ felder_1kreuzer =4
➢ felder_kreuzer = anzahl_kreuzer*felder_1kreuzer
➢ print("Anteil der Felder mit Kreuzern an der Gesamtzahl der Felder: t")
➢ print(felder_kreuzer / anzahl_felder_spielfeld)

12. Wiederholung Python (02_Variablen & Zuordnung)

Inspiriert von Monty Python, Guido van Rossum, Multi-Paradigmen, Interpreter,


dynamisch typisiert

2
Prüfungsvorbereitung MOS103_Informatik_I

13. Wiederholung Imports (02_Variablen & Zuordnung)

„Spoiler: Alles in Python ist ein Objekt“ so ist es wohl…

14. Variable in Python (02_Variablen & Zuordnung)

In einer Variable können Werte gespeichert werden (z.B. 3.142), eine Variable hat
einen Namen (z.B. pi), auf Variablen kann lesend und schreibend zugegriffen
werden, alles in Python ist ein Objekt und auch eine Variable, jedes Objekt hat einen
Typen, jedes Objekt hat eine ID

15. Objekte in Python (02_Variablen & Zuordnung)

Jedes Objekt hat eine ID, Abfrage: id(pi), jedes Objekt hat einen Typen, Abfrage:
type(pi)

16. Gültige Variablennamen in Python (02_Variablen & Zuordnung)

Großbuchstaben A bis Z, Kleinbuchstaben a bis z, Unterstrich, Zahlen 0 bis 9 (nicht


an erster Stelle), gerne alles klein geschrieben und mit Unterstrichen getrennt

hallo_? Ist nicht erlaubt, weil das Fragezeichen als Sonderzeichen nicht erlaubt ist.
Der Unterstrich ist das einzige erlaubte Sonderzeichen. Kleinbuchstaben von a bis z
erlaubt. 2-werte ist nicht erlaubt, weil an erster Stelle keine Ziffer stehen darf und das
Minuszeichen nicht erlaubt. variable_1 ist erlaubt, die Ziffer 1 ist erlaubt, da nicht an
erste Stelle. Unterstich an erster Stelle nur bei geschütztem Attribut. Nicht bei
Variable.

17. Der Unterstrich in Python (02_Variablen & Zuordnung)

… kennzeichnet eine Variable als implizit private

(veränderliche_variable = 1, _unveränderliche_variable = 1)

18. Tauschen Sie zwei Variable (02_Variablen & Zuordnung)

a=2, b=5, help=a, a=b, b= help

19. Tauschen Sie zwei Variable ohne Hilfsgröße (☺ Einschub ☺)

a=2, b=5, a=a+b (7), b=a-b (2), a=a-b (5)

(Vorsicht: a=a+b kann zur Bereichsüberschreitung führen)

Oder ganz einfach: x,y = y,x

20. Typen von Funktionen (02_Variablen & Zuordnung)

from math import sin, type(sin), builtin_function_or_method, sin hat eine id!

3
Prüfungsvorbereitung MOS103_Informatik_I

21. Integer in Python (02_Variablen & Zuordnung)

Alle Ganzzahligen Zahlen, auch negative Werte und die Null, eignen sich
hervorragend zum Zählen / Iterieren, lassen sich gut vergleichen (im Vergleich zu
Floats)

22. Floats in Python (02_Variablen & Zuordnung)

Gleitkommazahlen (3,142; 0.1; -2,5), normiert in der IEEE 754 Double Precision

23. Boolean in Python (02_Variablen & Zuordnung)

True / False bzw. 1 / 0

24. String in Python (02_Variablen & Zuordnung)

Text bzw. Aneinanderreihung von Zeichen, innerhalb Anführungszeichen („“ oder ‚‘)

Strings sind immutable!

25. Listen in Python (02_Variablen & Zuordnung)

Eine Liste enthält n Elemente, die mit einer Reihenfolge gespeichert sind, der String
Informatik enthält die 10 Buchstaben, die Buchstaben folgen einer Reihenfolge, d.h.
das kleine n folgt auf das große I, der Index beschreibt eine bestimmte Stelle in einer
Liste, Python ist Null-Indiziert, d.h. die erste Stelle hat den Index 0, für den Zugriff per
Index sieht Python eckige Klammern vor. z.B. x[0]=I

Listen sind mutable!


liste = ['a', 'b', 'c'], liste[0] = 1 ergibt [1, 'b', 'c']

26. Slicing von Listen (02_Variablen & Zuordnung)

X[Start:Stop:Intervall], x=‘Informatik‘, x[5:10] = ‘matik‘, x[::3] = ‚ioak‘

Das Intervall darf nicht 0 sein: x[::0] ergibt eine ValueError (slice stp cannot be zero)

Das Intervall „-1“ dreht die Liste um: x[::-1] = „kitamrofnI“

Strings sind immutable! Str = 'Informatik', str[0] = 'E' => TypeError


(‚str‘ object does not support item assignment)

27. Was bedeutet dynamisch typisiert? (02_Variablen & Zuordnung)

In einer dynamisch typisierten Sprache muss der Typ einer Variable nicht vorher
deklariert werden, d.h. x = Integer(), x = 10 ist z.B. nicht notwendig, x=10, type(x),
<class 'int'>, x=True, type(x), <class 'bool'>, x='Hello World', type(x), <class 'str'>

Durch die Zuweisung eines Wertes (mit einem bestimmten Typ) wird der Variable der
gleiche Typ zugeordnet (Variable wird typisiert)

4
Prüfungsvorbereitung MOS103_Informatik_I

28. Maximaler Integer (02_Variablen & Zuordnung)

Python springt intern von Integer auf Long, sobald maxsize überschritten wurde
import sys, sys.maxsize, sys.maxsize+1, type(sys.maxsize+1)
(9223372036854775807, 9223372036854775808, int)

29. Replacement in strings (02_Übungen)

zb = 'Blaukraut bleibt Blaukraut und Brautkleid bleibt Brautkleid'


zb1 =zb.replace('Blau','Grau')
zb2 =zb2.replace('Braut','Kraut')
# 'Graukraut bleibt Graukraut und Krautkleid bleibt Krautkleid'

30. Replacement in Listen (02_Übungen)

reihe = [0,0,0,0,0,0,0,0,0,0]
reihe_mit_boot = reihe
reihe_mit_boot[3] =1
reihe_mit_boot[4] =1
reihe_mit_boot
# [0, 0, 0, 1, 1, 0, 0, 0, 0, 0]

31. NumPy Bibliothek (02_Übungen)

NumPy ist ein Akronym für "Numerisches Python" ("Numerical Python"). Dabei
handelt es sich um ein Erweiterungsmodul für Python, welches zum größten Teil in C
geschrieben ist. Mit dem Importieren wird sichergestellt, dass die kompilierten
mathematischen und numerischen Funktionen und Funktionalitäten eine
größtmögliche Ausführungsgeschwindigkeit garantieren. Außerdem bereichert
NumPy die Programmiersprache Python um mächtige Datenstrukturen für das
effiziente Rechnen mit großen Arrays und Matrizen. Die Implementierung zielt sogar
auf extrem große ("big data") Matrizen und Arrays. Ferner bietet das Modul eine
riesige Anzahl von hochwertigen mathematischen Funktionen, um mit diesen
Matrizen und Arrays zu arbeiten.

32. SciPy Bibliothek (Einschub)

SciPy (Scientific Python) wird oft im gleichen Atemzug wie NumPy genannt. SciPy
erweitert die Leistungsfähigkeit von NumPy um weitere nützliche Funktionen, wie
zum Beispiel Minimierung, Regression, Fouriertransformation und vielen anderen.
Weder NumPy noch SciPy werden bei einer Standardinstallation von Python
installiert.

33. Matrizen in NumPy (02_Übungen)

# Eine Matrix in Numpy wird als Array bezeichnet. Mit dem Befehl np.zeros((Bre
Breite = int(10)
Höhe = int(10)
np.zeros((Breite, Höhe))

5
Prüfungsvorbereitung MOS103_Informatik_I

34. Wiederholung Variablen (03_ Rel. & Log. Op)

Lesender / Schreibender Zugriff, Zuordnung per = Operator, Name, Type, Wert,


Identität
Welche Bestandteile hat eine Variable?

35. Wiederholung Datentypen (03_ Rel. & Log. Op)

“Klassische” Python Datentypen: Integer, Float, String, Boolean, Liste,


Mutable / Immutable

36. Index-basierter Zugriff (03_ Rel. & Log. Op)

Strings und Listen speichern Elemente in Reihenfolge, Zugriff über den Index
(Python ist Null-Indiziert!), Slicing ermöglicht Zugriff auf Sequenzen,
s[START:STOP:INTERVAL]

37. Objekt in Python (03_ Rel. & Log. Op)

In Python wird ein Objekt durch 4 zentrale Kennungen beschrieben:

➢ Name – Der Bezeichner, mit dem der Wert aus der Session angesprochen
werden kann,
➢ Wert – Der im Speicher abgelegte Wert,
➢ Typ – Die Klasse des Objekts,
➢ ID – Der physikalische Speicherort des Objekts

38. Unterschied Mutable / Immutable (03_ Rel. & Log. Op)

Eine bedeutende Unterscheidung von Objekten in Python liegt in ihrer Fähigkeit zur
Veränderung. Es werden sog. Mutable- (veränderliche) von Immutable-
(unveränderliche) Objects unterschieden. Zu den Immutable-Objects zählen: int,
float, string, bool, decimal, complex, tuple, range, frozenset und bytes. Zu
den Mutable-Objects zählen: list, dictionary, set und User-definierte Objekte.
In Python wird ein Objekt durch 4 zentrale Kennungen beschrieben: Name, Wert,
Typ und ID. In Python ist ein Objekt immutable wenn es, sobald es einmal im
Speicher abgelegt ist, nicht wieder verändert werden kann – also alle oben
beschriebenen Objekteigenschaften konstant bleiben. Manchmal wird davon
gesprochen, das Objekt sei „hashable„. Dies bedeutet, dass die Klasse über eine
Methode __hash__ verfügt, deren Rückgabewert über die gesamte Zeit der Session
besteht. Dictionaries nutzen die Methode __hash__ für die interne Key-Value
Zuordnung. Da nur Immutable-Objects über eine solche Methode verfügen, können
auch nur sie als Keys in Dictionaries verwendet werden.
Ein Mutable-Object kann einzelne Eigenschaftswerte ändern und dabei seine
Speicheridentität beibehalten. Sind Objekte veränderbar, muss bei der Verwendung
vieler Methoden keine Zuweisung mehr auf das Objekt erfolgen. Man spricht davon,
das Objekt In-Place zu bearbeiten. Im Umgang mit Mutable-Objects ist Vorsicht
geboten. Eine Zuweisung auf ein neues Objekt erzeugt keine Kopie im Speicher,
sondern lediglich eine Kopie der Referenz auf den Speicher. Mit jeder Referenz die

6
Prüfungsvorbereitung MOS103_Informatik_I

in der Session auf einen bestimmten Speicherplatz zeigt, können Änderungen am


physikalischen Objekt vorgenommen werden. Verfügt eine Klasse über eine copy-
Methode, ist dies ein sehr guter Hinweis darauf, dass es sich um einen Mutable-
Objekttyp handelt. Mit der Methode erstellen wir explizit eine Kopie des Objekts (bei
Immutable-Objekten wird ohnehin immer kopiert und es machte keinen Sinn, eine
explizite Methode dafür bereitzustellen).

39. Warum ist es schwierig, die Zahl Pi im Computer abzubilden? (03)

Reine Mathematiker lehnen numerische Mathematik vollständig ab, angewandte


Mathematiker haben mit Pi kein Problem. Was soll die Frage?
Man kann beweisen, dass Pi eine irrationale Zahl ist, d.h. Pi kann nicht als Bruch
zweier ganzer Zahlen dargestellt werden. Darüber hinaus ist die Zahl Pi sogar
transzendent, hat also keine algebraische Darstellung. Pi hat folglich unendlich viele
Nachkommastellen. Derzeit hält Google den Rekord hinsichtlich der Anzahl der
berechneten Nachkommastellen mit 31 Billionen. Die NASA beschränkt sich auf
3,141592653589793, entsprechend 15 Nachkommastellen (aufgerundet). Voyager I
hat als erstes Objekt die äußere Grenze unseres Sonnensystems überschritten und
ist zurzeit rund 20,1 Milliarden Kilometer von der Erde entfernt. Nimmt man diese
Entfernung als den Radius eines Kreises und berechnet daraus den Umfang, dann
kommen etwas mehr als 125 Milliarden Kilometer heraus. Die Ungenauigkeit durch
die verkürzte Kreiszahl π beträgt dadurch nur rund 3,8 Zentimeter.
Heute sind selbst in Taschenrechnern Näherungsfunktionen, Tabellen oder
Reihenentwicklungen implementiert. Auf diese Weise berechnet man z.B. einfach
acos(-1.).

40. Was bedeutet Arität? (03_ Rel. & Log. Op)

Der Begriff Stelligkeit (auch Arität; englisch arity) steht für die Anzahl der Argumente
einer Verknüpfung, einer Abbildung bzw. eines Operators oder in der Informatik für
die Parameteranzahl von Funktionen, Prozeduren oder Methoden. Allgemeiner kann
dieser Begriff auch auf Relationen angewendet werden.
Beispiel: 1+2=3, der Operator „+“ hat die Arität 2.
Im Prinzip haben sämtliche relationalen Operatoren die Arität 2.

41. Zusammenfassung Relationale Operatoren (03_ Rel. & Log. Op)

Vergleich zweier Variablen miteinander (Arität = 2), Verschiedene Typen können als
Operanden verwendet werden, das Ergebnis ist immer vom Typ Boolean

42. Anweisungsblock in Python (03_ Rel. & Log. Op)

Python kennt kein explizites Begin / End, jeder Anweisungsblock ist 4 Leerzeichen
tiefer eingerückt als der umgebende Code, der Anweisungsblock endet mit dem
Ende der Einrückung

43. Elemente von Mengen, die selbst Elemente sind (03_ Rel. & Log. Op)

menge = [[1,2,3], [5, 6, 7], ['a', 'b', 'c'],[8,9,10]], menge[0][1], 2

7
Prüfungsvorbereitung MOS103_Informatik_I

44. Relationale Operationen in Python (03_ Rel. & Log. Op)

Größer >, kleiner <, größer gleich >=, kleiner gleich <=, (identisch) gleich ==,
ungleich !=

45. Variablen welchen Datentyps sind vergleichbar? (03_ Rel. & Log. Op)

Im Prinzip alle Operanden des gleichen Typs, d.h. Int-int, long-long, float-float, str-str,
list-list usw. Weiterhin zulässig sind Vergleiche „ähnlicher“ Typen, z.B. reine Zahlen,
wie int-long, int-float, long-float
Nicht möglich ist der Größenvergleich komplexer Zahlen, d.h. import cmath, 2+4j <
4+8j, führt zum TypeError '<' not supported between instances of 'complex' and
'complex'. Allerdings gestatten komplexe Zahlen logische Vergleiche, import
cmath,2+3j != 4+6j liefert True
Sämtliche anderen “wesensfremden” Größenvergleiche, z.B. Zahl mit Text, führen
zum TypeError: '<' not supported between instances of 'int' and 'str', dagegen sind
logische Operationen erlaubt: 'a' == 3 liefert False
'abc'<'abc' False, 'ab'<'abc' True, 'xy'<'ab' False, 'xy'<'xyz' True
Aber 'xy'<'abc' False (!), offenbar wird die Länge des strings zuerst verglichen

46. Welche Kurzzeichen für logische Operationen gibt es? (03_ Rel. & Log. Op)

Logisches ODER: |, logisches UND: &, logisches XOR: ^,

47. XOR (^) in Python am Beispiel 7^10 (binär: 0111 ^ 1010) (03_ Rel. & Log. Op)

Logisches ODER: 0111 OR 1010 = 1111, dezimal 15 (7 | 10)


Logisches UND: 0111 AND 1010 = 0010, dezimal 2 (7 & 10)

48. IF in Python (Bedingte Anweisung, 03_ Rel. & Log. Op)

if (logische Bedingung): (Doppelpunkt am Ende)


Anweisung (4 Leerzeichen eingerückt, bei erfüllter Bedingung ausgeführt)
….weitere Zeilen der Anweisung
elif (weitere logische Bedingung, Doppelpunkt am Ende)
Anweisung 2, 4 Leerzeichen eingerückt, wird bei erfüllter Bedingung 2 ausgeführt
….weitere Zeilen der Anweisung 2
else: (Doppelpunkt am Ende)
Anweisung für den else-Fall, 4 Leerzeichen eingerückt

8
Prüfungsvorbereitung MOS103_Informatik_I

Die Zeile „else:“ enthält keine explizite logische Bedingung, sie betrifft sämtliche
sonstigen Fälle, die weder die 1. noch die 2. logische Bedingung erfüllen.
if, elif und else immer mit Doppelpunkt abschließen

49. IF in Python (Bespiel, 03_Übungen)

if(Limette==0 and Sirup==0 and Eis==True and ……and Orangensaft==2 ):


print("Tequila Sunrise")
else:
print("kein Tequila Sunrise")

50. Wie viele Alternativen können Sie bei einer If Verzweigung prüfen?

Antwort: Eine Alternative je Zweig, die dann True oder False ist,
➢ entweder mit if, elif, else in einer Spalte. Kann theoretisch unendlich weit
ausgedehnt werden. Mit If beginnt Verzweigung, Elif mittlerer Teil, Else Ende.
Ausschließlich if in einer Spalte geht also nicht. Wird verwendet, wenn
Bedingung keine weitere wahre Alternative hat. Genau einmal wahr und
einmal falsch.
➢ oder es gibt nur if-Zweige, kein Elif und Else. Mit mehreren versetzten if-
Zweigen kann eine Aussage, die mehrere wahre Alternativen hat, überprüft
werden. Ab einer falschen Aussage springt der Computer in den weniger
versetzten if-Zweig. Schaltjahr-Beispiel: Wenn 1600 % 4 dann ist es ein
Schaltjahr, wenn 1600 % 400 ist es auch ein Schaltjahr. Kann theoretisch
unendlich weit ausgedehnt werden.

51. Mengenschleifen in Python „for Variable in [liste]:“ (04_Schleifen)

Über die Inhalte einer Menge wird eine Schleife ausgeführt, die Schleife ermöglicht
es, Code wiederholt auszuführen, eine Menge kann jedes iterierbare Element in
Python sein, Beispiele:
for buchstabe in 'Wort':
for zahl in [90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]:
auftrags_liste = [1000, 1001, 1434, 1801, 1912, 2303, 2300]
for temperatur in auftrags_liste:
Die for-Zeile wird mit einem Doppelpunkt abgeschlossen.

52. Zählschleifen in Python „for Variable in range(Start,Stop,Schrittweite):”


(04_Schleifen)

Schleife wird von Start bis Stop ausgeführt, ggf in Schritten von Schrittweite. Wie bei
Mengenschleifen wird Code wiederholt ausgeführt, in der Zählschleife können nur
Zahlen iteriert werden. Beispiel: for i in range('a','t'): führt zum TypeError 'str' object
cannot be interpreted as an integer,

for I in range(4) print I führt zur Ausgabe 0-1-2-3, range(4) entspricht also range(0,4)

for i in range(1,100,8) führt zur Ausgabe 1,9,17,25,33,41…

for i in range(100,1,-8) führt zur Ausgabe 1100,92,84,76,68,…

9
Prüfungsvorbereitung MOS103_Informatik_I

Die Zählschleife basiert auf der Mengenschleife, d.h. der range kann als
spezielle Menge angesehen werden.

Die for-Zeile wird mit einem Doppelpunkt abgeschlossen. Prameter Start, Stop und
Schrittweite zum range jeweils durch Komma getrennt.

53. Break Keyword (04_Schleifen)

Es kann sinnvoll sein, aus einer Schleife vorzeitig auszusteigen, z.B.


Suchalgorithmus: Sobald ein Treffer gefunden wird, beende Iteration, break beendet
hierbei immer die nächst-höhere Schleife

54. Beispiel für Break Keyword (03, 04_Schleifen)

while True :
zeile = random.randint(0,10)
spalte = random.randint(0,10)
print(zeile,spalte)
if(zeile==4 and spalte==5):
print("Treffer bei Zeile ",zeile, "und Spalte ",spalte)
feld[4][5]=0
break

55. Fußgesteuerte Schleife (04_Schleifen)

Eine Schleife, deren Abbruch am Ende einer Iteration geprüft wird ist fußgesteuert,
auch in der letzten Iteration wird die Berechnung noch durchgeführt, die Berechnung
wird immer mindestens einmal durchgeführt

56. Kopfgesteuerte Schleife (04_Schleifen)

Hier wird die Bedingung geprüft, bevor die Schleife startet, ggfs. wird der Hauptteil
der Schleife nicht ausgeführt, kann mit einem Else kombiniert werden
Beispiel:

57. Steuerung von Schleifen in Python (Einschub)

Mit Schleifen und Bedinge Anweisungen können Listen durchlaufen oder sogar ganz
bequem aufgebaut werden. Es gibt in Python zwei Schleifen, einmal die For-Schleife

10
Prüfungsvorbereitung MOS103_Informatik_I

und einmal die While-Schleife. Beide Schleifen sind kopfgesteuert, d.h. die
Bedingung wird vor der Abarbeitung geprüft.

Es gibt kein BEGIN.

58. While…Else (04_Schleifen)

Führe den Code aus, solange die Bedingung True ist, das Else wird nur ausgeführt,
wenn die Bedingung von While False ist

59. Continue Keyword (04_Schleifen)

Es kann sinnvoll sein, ein Element einer Schleife zu überspringen, z.B. um


aufwendige Berechnungen zu ersparen. Mit dem Continue Keyword wird der Rest
der aktuellen Iteration übersprungen. Typische Anwendung ist ein Flase-Ergebnis
einer Abfrage.

60. List comprehension (04_Schleifen)

Eine Schleife und eine Liste sind beide iterierbar, mit vereinfachter Syntax kann die
Schleife direkt in die Liste übertragen werden; kann mit Verzweigungen kombiniert
werden. Beispiel:
liste1=[1,2,3],
liste2 = [i*i for i in liste1] (=[1,4,9])
liste3 = [i*i*I for I in liste 1 if i%2 != 0] (= [1,27])
liste4 = [i*i*I for I in range(0,4)] (=[0,1,8,28]) (Range ist eine Form von Liste)

61. Unified Modeling Language (UML) (04_Schleifen)

Generische Modellierungssprache, verschiedene Diagramtypen, Strukturdiagramme,


u.a. Klassendiagramme, Verhaltensdiagramme, u.a. Aktivitätsdiagramm
Rahmen/Prozessbeschreibung

Jeder Prozess hat einen Anfang und mindestens ein Ende, mehrere Enden sind
möglich (start – stop)

Das Ende entspricht dem geplanten Ende des Prozesses, bei Auftritt eines Fehlers
kann der Prozess auch abgebrochen werden

11
Prüfungsvorbereitung MOS103_Informatik_I

Jeder Prozess beinhaltet Aktivitäten, z.B. Platziere Schiff an Koordinate, Kasten mit
runden Ecken

Objekte beinhalten Daten, z.B. Länge des Schiffs, Kasten mit rechtwinkeligen Ecken

Kontrollfluß: Verbindung von Aktivitäten und Objekten, definiert den Ablauf des
Prozesses, kann beschriftet werden

Verzweigung: Bildet If/Then Konstrukte ab, z.b. dchieße, bis Spiel beendet, Raute mit
Kontrollflüssen

Schleife:
Eine Schleife benötigt zum Abbruch auch immer eine Bedingung, offensichtlich für
die While-Schleife, bei einer Zähl- oder Mengenschleife am Ende der Menge,
Kontrollfluß wird zur Bedingung zurückgeführt, z.B. Schieße auf Spielfeld bis
abgeräumt

12
Prüfungsvorbereitung MOS103_Informatik_I

Platzhalter: Prozesse können schnell komplex werden, um ein Durcheinander an


Linien zu vermeiden, können Platzhalter eingeführt werden

62. Eigenschaften einer Funktion (05_Funktionen_Exceptions)

Abstraktion, Parameter sind vor dem Nutzer “versteckt”, Wiederverwendbarer Code,


wichtige Parameter können übergeben werden, Verständlichkeit, das
Hauptprogramm bleibt verständlich und kurz, Dokumentation kann eingebunden
werden

63. Dokumentation von Funktionen (05_Funktionen_Exceptions)

Die Dokumentation lässt schnell erkennen, was passiert und erleichtert die Suche
nach der passenden Funktion, zusätzlich ist die Dokumentation vollständig und
erklärt alle möglichen Optionen, die Dokumentation erklärt die Implementierung, sie
kommentiert nicht Zeile für Zeile den Code. Beispiel:
def randint(self, low, high=None, size=None, dtype=int):
""" # Beginn der Dokumentation
randint(low, high=None, size=None, dtype='l')
Return random integers from `low` (inclusive) to `high` (exclusive)….

""" # Ende der Dokumentation

Regeln:
• Geben Sie eine einzeilige Zusammenfassung an
• Eine Leerzeile
• Erläutern Sie die Details der Implementierung
• Geben Sie an, was das Ergebnis der Funktion ist!

64. Beispiel für eine Dokumentation (05_Funktionen_Exceptions)

def schliesse_rollo():

13
Prüfungsvorbereitung MOS103_Informatik_I

""" (Beginn durch """)


Zeigt ein geschlossenes Rollo auf dem Bildschirm an. (Zusammenfassung)
(Leerzeile)
Nutzt verschiedene ASCII Symbole, um den Eindruck eines geschlossenen
Rollos zu erzeugen. Die Rahmen des Fensters sind als Pipe und Bindestrich
codiert. Für die Darstellung der Rollos wird das Plus zeichen verwendet.
Die Ausgabe erfolgt über print auf stdout. (Details/Ergebnis)
""" (Ende durch """)
65. Lokale und globale Variablen (05_Funktionen_Exceptions)

y=1
def inkrement_y():
global y # definiert y als globale Variable
y+=1 # erhöht die globale Variable y um 1

print(y)
inkrement_y() # Aufruf !ohne! Argument
print(y)

Eine fehlende Zeile “global y” führt zu einem “UnboundLocalError: local variable 'y'
referenced before assignment”
Mit “global y” spielt die Funktion inkrement_y() überhaupt keine Rolle.

66. Namespace (05_Funktionen_Exceptions)

Innerhalb einer Funktion gilt ein eigener Namespace, um auf Variablen außerhalb
des Namesspace zugreifen zu können, müssen Sie über das „global“ Keyword
importiert werden. Der Namespace der Funktion ist nicht außerhalb der Funktion zu
erreichen.

67. Namespace (Ergänzung)

“Name”, auch Identifier (Bezeichner) genannt, ist ein Name, der Objekten gegeben
wird. Alles in Python ist ein Objekt. “Name” bietet die Möglichkeit, auf das zugrunde
liegende Objekt zuzugreifen. “Namespace” ist eine Sammlung von Namen. Die
Sammlung aller Namen einer Namespace wird den entsprechenden Objekten
zugeordnet. Zu einem bestimmten Zeitpunkt können verschiedene Namespaces
nebeneinander existieren, sind jedoch vollständig isoliert. Ein Namespace mit allen
(integrierten) Namen wird beim Starten des Python-Interpreters erstellt (der sog.
built-in namespace). Dies ist der Grund, warum integrierte Funktionen wie id (), print
() usw. von jedem Teil des Programms immer zur Verfügung stehen. Jedes Modul
erstellt einen eigenen globalen Namespace. Diese verschiedenen Namespaces sind
isoliert. Daher kollidiert der gleiche Name, der ggf. in verschiedenen Modulen
vorhanden ist, nicht. Module können verschiedene Funktionen und Klassen haben.
Ein lokaler Namespace wird erstellt, wenn eine Klasse definiert oder eine Funktion
aufgerufen wird. Obwohl verschiedene eindeutige namespaces definiert sind, kann
nicht von jedem Teil des Programms aus auf alle namespaces zugegriffen werden.
Das Konzept des “Geltungsbereichs” (scope) kommt ins Spiel. Scope ist der Teil des
Programms, von dem aus ein Namespace direkt ohne Präfix aufgerufen werden
kann. Zu jedem Zeitpunkt gibt es mindestens drei verschachtelte Bereiche.

14
Prüfungsvorbereitung MOS103_Informatik_I

• Scope der aktuellen Funktion, die lokale Namen beinhaltet


• Scope des Moduls mit globalen Namen
• Äußerster scope mit (allen) integrierten Namen

Wenn innerhalb einer Funktion ein Verweis erstellt wird, wird der Name zuerst im
lokalen Namespace, dann im globalen Namespace und schließlich im integrierten
(built-in) Namespace gesucht. Befindet sich eine Funktion in einer anderen Funktion,
wird ein neuer Bereich im lokalen Bereich verschachtelt.

1. def outer_function ():


2. b = 20
3. def inner_func ():
4. c = 30
5. a = 10

Hier befindet sich die Variable a im globalen namespace. Die Variable b befindet sich
im lokalen namespace von outer_function () und c im verschachtelten lokalen
namespace von inner_function ().

Wenn wir uns in inner_function () befinden, ist c für uns lokal, b ist nicht lokal und a
ist global. Wir können c lesen und neue Werte zuweisen, aber wir können von
inner_function () die Werte von b und a nur lesen. Wenn wir versuchen, b als Wert
zuzuweisen, wird eine neue Variable b im lokalen Namespace erstellt, die sich vom
nichtlokalen b unterscheidet. Dasselbe passiert, wenn wir a einen Wert zuweisen.
Wenn wir jedoch a als global deklarieren, gehen alle Referenzen und Zuweisungen
an das globale a. Wenn wir die Variable b erneut binden möchten, muss sie ebenfalls
als nicht lokal deklariert werden. Das folgende Beispiel wird dies weiter
verdeutlichen.

def outer_function():
a = 20
def inner_function():
a = 30
print('a =',a)

inner_function()
print('a =',a)

a = 10
outer_function()
print('a =',a)

Das Programm gibt a = 30, a = 20, a = 10 aus.

68. Call by Value, Call by Reference (05_Funktionen_Exceptions)

Was passiert, wenn eine Funktion den übergebenen Wert ändert?


Es existieren hierfür zwei Varianten: 1) Call by Value: Nur der Wert wird übergeben
2) Call by Reference: Das ganze Objekt wird übergeben;

15
Prüfungsvorbereitung MOS103_Informatik_I

In Python läuft es wieder auf Mutable / Immutable hinaus..

69. Call by Value, Call by Reference (Ergänzung aus anderen Sprachen)

Die Call-by-Value-Methode kopiert bei C, C++, … den Wert eines Arguments in den
formalen Parameter der (aufgerufenen) Funktion. Änderungen am Parameter der
Hauptfunktion wirken sich daher nicht auf das Argument aus. Bei dieser
Parameterübergabemethode werden Werte von Aktualparametern in die
Formalparameter der Funktion kopiert und die Parameter an verschiedenen
Speicherorten gespeichert. Änderungen, die innerhalb von Funktionen vorgenommen
werden, wirken sich also nicht auf die tatsächlichen Parameter des Aufrufers aus.
Die Call-by-Reference-Methode kopiert die Adresse eines Arguments in den
Formalparameter. Bei dieser Methode wird die Adresse verwendet, um auf das im
Funktionsaufruf verwendete Argument zuzugreifen. Dies bedeutet, dass Änderungen
am Parameter das übergebende Argument ändern. Bei dieser Methode entspricht
die Speicherzuordnung den Aktualparametern. Alle Operationen in der Funktion
werden mit dem Wert ausgeführt, der unter der Adresse des aktuellen Parameters
gespeichert ist, und der geänderte Wert wird unter derselben Adresse gespeichert.

In Python gibt es weder ein "call-by-reference" noch "call-by-value" im


klassischen Sinn, weil in Python eine Variable kein Alias für einen Speicherort
im Speicher darstellt. Es handelt sich lediglich um eine Bindung an ein Python-
Objekt.
Python verwendet einen Mechanismus, der als "Call-by-Object" bezeichnet wird und
manchmal auch als "Call by Object Reference" oder "Call by Sharing" bezeichnet
wird. Wenn man unveränderliche Argumente wie Ganzzahlen, Zeichenfolgen oder
Tupel an eine Funktion übergibt, verhält sich die Übergabe wie "call-by-value". Die
Objektreferenz wird an die Funktionsparameter übergeben. Sie können innerhalb der
Funktion nicht geändert werden, da sie überhaupt nicht geändert werden können, d.
h. sie sind immutable. Bei der Übergabe veränderbare Argumente wird ebenfalls die
Objektreferenz übergeben, diese kann jedoch in der Funktion geändert werden
aufgrund der Objekteigenschaft mutable.

70. Mit welchen Mechanismen können Sie Informationen vom Namespace des
Hauptprogramms in den einer Funktion übertragen?
➢ Schlüsselwort global bei Variablennamen (mit Vorsicht benutzen, weil
fehleranfällig)
➢ Parameterliste (Parameter die vom Main an die Funktion übergeben werden
können)
➢ Parametername im Main muss nicht, kann aber identisch mit denen im
Funktionsnamenraum sein. Im Main-Namensraum sind die Namen der
Variablen das Funktionsnamenraum nicht bekannt.

71. Mit welchen Mechanismen können Sie Informationen von der Funktion
zurück in das Hauptprogramm übertragen?
➢ call by reference (nicht call by value), return

16
Prüfungsvorbereitung MOS103_Informatik_I

➢ call by reference: Wird realisiert mithilfe von Listen, bei denen einzelne
Elemente ersetzt werden. Nach Änderung der Elemente durch die Funktion ist
die Liste nachhaltig verändert worden.
➢ call by value: Der Wert von Variablen oder die Elemente eines strings können
innerhalb der Funktion geändert werden. Der geänderte Wert der Variable
oder der geänderte string bleibt im Funktionsnamenraum und wird nicht an
den Main-Namenraum übergeben. Eignet sich daher nicht um Informationen
zurück ins Hauptprogramm zu übertragen.
➢ return: Verwendung bei Funktionen zum Zurückgeben von Werten an Main

72. Optionale Parameter (05_Funktionen_Exceptions)

Nicht jeder Parameter einer Funktion muss beim Aufruf übergeben werden, wenn ein
DefaultWert implementiert wurde, verbessert die Abstraktionsfähigkeit einer
Funktion, ermöglicht aber dennoch detaillierte Anpassungen für fortgeschrittene
Anwendungen. Beispiel:
➢ def schliesse_rollo(hoehe, symbol='x'):
➢ """
➢ print('|--------------|')
➢ for _ in range(hoehe): # Die Zaehlvariable wird nicht benoetigt, daher _
➢ print('|'+14*symbol+'|')
➢ print('|--------------|'
Noch ein Beispiel:
➢ test=4
➢ symbol=“x“
➢ for _ in range(test) # oder auch: for nonsense in range(test)
➢ print(symbol)

73. Rückgabewert einer Funktion (05_Funktionen_Exceptions)

Funktionen geben Werte zurück, neu erzeugter / veränderter Wert, z.B.: Erfolg / nicht
Erfolg der Funktion, wir nutzen hierfür das Return Keyword.

Eine return-Anweisung beendet die Ausführung des Funktionsaufrufs und "gibt" das
Ergebnis, d.h. den Wert des Ausdrucks nach dem return-Schlüsselwort, an den
Aufrufer zurück. Wenn die return-Anweisung keinen Ausdruck enthält, wird der
spezielle Wert None zurückgegeben. Wenn der Funktionscode keine return-
Anweisung enthält, endet die Funktion, wenn der Kontrollfluss das Ende des
Funktionskörpers erreicht und der Wert "None" zurückgegeben wird.

74. None (05_Funktionen_Exceptions)

None ist nichts, per Definition, None hat seinen eigenen Datentyp (>>> type(None)
<class 'NoneType'>), nicht mit NaN (Not a Number) zu verwechseln, eine Funktion
ohne Rückgabewert gibt immer None zurück.
x = None
if x:
print("Do you think None is True")
else:

17
Prüfungsvorbereitung MOS103_Informatik_I

print("None is not True...") None is not True...

None is false, but only None can be None ☺

75. NaN (not a number) (Einschub)

float(„nan“) ergibt nan, kann mit math.isnam geprüft werden


➢ x=“nan“ # type(x) -> str
➢ y=float(x) # type -> nan
➢ import math
➢ math.isnam(y)
➢ True
Möglich ist auch der Test, ob ein nan gleich ist zu sich selbst ist
➢ x=float(“nan“)
➢ x==x
➢ False
bzw.
➢ def isNaN(num)
➢ return num != num
Funktioniert auch mit pandas und numpy:
➢ Import pandas as pd
➢ Import numpy as np
➢ Import math
➢ x1 = float(“nan“)
➢ printf(f“It’s pd.isna : {pd.isna(x1}“)
➢ printf(f“It’s np.isna : {np.isna(x1}“)
➢ printf(f“It’s math.isna : {math.isna(x1}“)
“It’s pd.isna : True
“It’s np.isna : True
“It’s math.isna : True

76. Exception (05_Funktionen_Exceptions)

Python (die int Funktion) hat eine “Exception geworfen”, die Exception war ein
“ValueError”: Aus einem String kann kein Integer erzeugt werden, die Exception hat
das Programm beendet. Um eine sinnvolle Prüfung des Strings zu ermöglichen,
muss die Exception abfangen werden
try:
user_input = int(input('Bitte geben Sie Ihren PIN ein: '))
except ValueError:
print('Bitte geben Sie eine Zahl ein!')

Exceptions müssen auch erzeugt werden.

77. Pass Keyword (05_Funktionen_Exceptions)

Das pass-Statement "pass" ist eine Nulloperation. Wenn „pass“ ausgeführt wird,
passiert nichts. „pass“ ist als Platzhalter nützlich, wenn eine Anweisung syntaktisch
erforderlich ist, aber kein Code ausgeführt werden muss. Beispiel:

18
Prüfungsvorbereitung MOS103_Informatik_I

def f (arg): pass # eine Funktion, die nichts tut

class C: pass # eine Klasse ohne Methoden


„pass“ macht nichts, kann aber beim Abfangen einer Exception verwendet werden,
um die Erzeugung der Fehlermeldung zu unterdrücken.

78. Finally Keyword

Es kann notwendig sein, vor Ende des Codes/Programms noch Schritte


durchzuführen, dafür kann das Finally Keyword verwendet werden, z.B.: Bevor das
Programm beendet wird, wird der PIN Finally wird ausgeführt unabhängig davon, ob
der Fehler korrekt abgefangen wurde.
➢ def func1():
➢ try:
➢ return 1 # ignoring the return
➢ finally:
➢ return 2 # returns this return
func1() gibt den Wert 2 zurück

➢ def func2():
➢ try:
➢ raise ValueError()
➢ except: # is going to this exception block, but ignores the return
➢ return 1
➢ finally:
➢ return 3
Func2() gibt den Wert 3 zurück

➢ def func3():
➢ return 0 # finds a return here and will use this return
➢ try:
➢ raise ValueError()
➢ except:
➢ return 1
➢ finally:
➢ return 3
Func3() gibt den Wert 0 zurück

79. Lebenszyklus einer Software (06_Software Entwicklung) und


(Wiederholung 07)

Initialisierung – Planung – Anforderungsanalyse – Entwurf – Entwicklung – Test –


Auslieferung - Betrieb & Wartung - Disposition

79.1 Initialisierung (06_Software Entwicklung)

Bevor Sie irgendetwas machen, brauchen Sie eine Idee, bevor Sie irgendetwas
machen können, benötigen Sie einen Auftrag, ein Projektsponsor beauftragt Sie, ein
Projekt zu planen; damit ist das Projekt selber noch nicht beauftragt, aber Sie sind
beauftragt ein Projekt zu planen =>Projektauftrag

19
Prüfungsvorbereitung MOS103_Informatik_I

79.2Planung (06_Software Entwicklung)

Was soll bis wann und von wem in welcher Qualität erledigt werden, wieviel wird das
Kosten, welche Risiken verbergen sich in diesem Plan, ein Projektplan ist nicht in
Stein gemeißelt, sondern passt sich immer dem aktuellen Status des Projektes an
=>Projektplan

79.3Anforderungsanalyse (06_Software Entwicklung) (Wiederholung 07)!

Bevor Sie ein Produkt entwickeln, müssen Sie festlegen, was es können soll. Es geht
dabei nicht um die konkrete technische Umsetzung, sondern um die abstrakte
Funktionalität, alle Beteiligten müssen in diesem Schritt gehört werden;
insbesondere geht es um die allgemeinen Anforderungen an das Produkt =>
Lastenheft / User Stories
➢ Anforderungsliste erstellen
➢ Stakeholder abholen
➢ Funktionelle und nichtfunktionelle Anforderungen mitteilen

79.4Design – Entwurf (06_Software Entwicklung) (Wiederholung 07)!

Nach der Analyse der Anforderungen: Wie setzen Sie das jetzt alles um, welche
Technologien verwenden Sie? Teile und herrsche: Aus welchen Komponenten
bauen Sie die Software auf? Jetzt ist der richtige Zeitpunkt für Aktivitäts- und
Klassendiagramme! => Pflichtenheft

79.5Entwicklung (06_Software Entwicklung)

Tatsächliche Umsetzung, Programmieren der Software, Implementierung der


Infrastruktur, orientiert sich am Pflichtenheft, möglichst enge Interaktion mit Tests
➢ Code schreiben
➢ Versionierung
➢ Gitflow

79.6Test (06_Software Entwicklung)

Versuchen Sie so früh wie möglich zu testen, damit Fehler günstig zu beheben sind,
Tests sollten insofern möglichst automatisiert werden, Code-Coverage > 90%, Dev-
Test-Prod Umgebungen nutzen, Tests sollten gegen das Lastenheft prüfen!

79.7Auslieferung (06_Software Entwicklung)

Das Produkt geht live! Ein erster abgeschlossener Stand der Software wird
veröffentlicht, Kundenzugang ist möglich, dieser kann in Phasen (alpha, beta, nightly
build) geteilt werden

79.8Betrieb & Wartung (06_Software Entwicklung)

Wie gehen Sie mit Bugs um, wie schnell reagieren Sie, wie schnell fixen Sie die
Bugs (SLA: Service Level Agreement), wie überwachen Sie den Betrieb, wann
benötigen Sie neue Ressourcen?

20
Prüfungsvorbereitung MOS103_Informatik_I

79.9Disposition (06_Software Entwicklung)

Auch Software muss recycelt werden, Beachten von Gewährleistungs- und andern
Pflichten, korrekter Umgang mit sensiblen Daten, korrekter Umgang mit bestehender
Infrastruktur.

80. Agile Software Entwicklung (wo bin ich hier?) (06_Software Entwicklung)

1. Our highest priority is to satisfy the customer through early and continuous
delivery of valuable software.
2. Welcome changing requirements, even late in development. Agile processes
harness change for the customer’s competitive advantage.
3. Deliver working software frequently, from a couple of weeks to a couple of
months, with a preference to the shorter timescale.
4. Business people and developers must work together daily throughout the project.
5. Build projects around motivated individuals. Give them the environment and
support they need, and trust them to get the job done.
6. The most efficient and effective method of conveying information to and within a
development team is face-to-face conversation.
7. Working software is the primary measure of progress.
8. Agile processes promote sustainable development. The sponsors, developers,
and users should be able to maintain a constant pace indefinitely.
9. Continuous attention to technical excellence and good design enhances agility.
10. Simplicity–the art of maximizing the amount of work not done–is essential.
11. The best architectures, requirements, and designs emerge from self-organizing
teams.
12. At regular intervals, the team reflects on how to become more effective, then
tunes and adjusts its behavior accordingly.

81. Was halten Sie für mögliche Nachteile Agiler Vorgehensweisen


(Wiederholung 07!)?

Es ist umstritten, ob der Entstehungsprozess von Software so gut verstanden


wird, dass eine planmäßige Herstellung möglich ist: Kritiker argumentieren, dass
Software nichts anderes sei als „ausführbares Wissen“. Wissen jedoch lässt sich
nicht ingenieursmäßig herstellen, wie sich etwa eine Brücke oder ein Hochhaus
herstellen lässt, sondern wird in einem kreativen Prozess gefunden. Mit ein Grund
dafür ist, dass sowohl die Ziele, als auch das Umfeld (beteiligte Personen, Marktan-
forderungen, technisches Umfeld/Schnittstellen) flexibel sind und sich im Laufe der
Zeit ändern. Die agilen Methoden eignen sich daher besonders gut, um auf
geänderte Anforderungen zu reagieren, da die Entwicklungszyklen in der Regel von
vornherein nicht lange angelegt sind. Die Anforderungen werden in der Regel nur mit
Kurzbeschreibungen festgehalten und erst kurz vor Beginn von Umsetzung und
Testvorbereitung ausformuliert. Durch die kurzen Zeiträume sind die Anforderungen
relativ frei von nachträglichen Änderungen. Allerdings verbieten weder das V-Modell
noch RUP den Einsatz von agilen Elementen, wie Rapid Prototyping; weder vor noch
während der Phasen Anforderungsdefinition oder Design. Generell ist in Projekten
ein agiles Vorgehen notwendig, allein schon um die Änderungen, die ein Projekt
zwangsläufig mit sich bringt, zu berücksichtigen und zu integrieren.
Vorgehensmodelle helfen dabei, diese Änderungen geregelt ins Projekt

21
Prüfungsvorbereitung MOS103_Informatik_I

aufzunehmen. Beim Vertragsabschluss müssen die Eigenschaften der agilen


Vorgehensweise ausreichend berücksichtigt sein. Klare inhaltliche Vorgaben
(Pflichtenheft) sind schwerlich möglich, da die Anforderungen per Definition erst zur
Projektlaufzeit entwickelt werden. Bedingt durch die mediale Aufmerksamkeit,
werden agile Methoden manchmal fälschlicherweise als Allheilmittel bei
Projektproblemen angesehen. Dies ist logischerweise nicht so: Die
Haupthinderungsgründe (siehe auch Projektindikatoren) gelten für agile Verfahren
genauso wie für traditionelle Verfahren.

82. Was halten Sie für mögliche Nachteile Agiler Vorgehensweisen


(aus Informatik II)?

➢ hohes Maß an eigener Disziplin


➢ Bei mehreren Parteien außerhalb einer Organisation schwer zu realisieren,
weil Interessenkonflikt (Beispiel außerhalb einer Organisation: Brückenbau,
Bauunternehmen hat mehrere Brücken zu bauen und nicht nur eine
➢ benötigte Zeit kann schwer abgeschätzt werden, weil im Verlauf des Projekts
immer neue Anforderungen hinzukommen.
➢ "Roter Faden" kann verloren gehen
➢ Bei immer neuen Terminen muss auch etwas beschlossen werden
(Anforderungen nehmen dadurch immer mehr zu)

83. Was halten Sie für mögliche Vorteile Agiler Vorgehensweisen (aus
Informatik II)?
84.
➢ Menschen sind wichtiger als Prozesse und Werkzeuge
➢ Schneller Projektstart
➢ Hohe Flexibilität, weil direkter Einfluss auf den Projektverlauf
➢ Starke Einbeziehung der Nutzer
➢ Frühes Einsteigen der Codierung
➢ Fehler werden durch beständiges Testen früh erkannt => Weiterentwicklung
der Architektur (Grundlage für das Testen von Code. Bei „starren“
Projektmanagement ist der oft ausufernde zeitliche Aufwand für das Testen
nicht abfangbar.)

85. Scrum (wo bin ich hier?) (06_Software Entwicklung)

Eine Implementierung Agiler Entwicklung, eine iterative Umsetzung klassischer


Projekt-Management Ansätze. Zu den Inhalten von Scrum gehören Ereignisse,
Rollen und Artefakte

86. Sprint (wo bin ich hier?) (06_Software Entwicklung)

Eine feste, immer gleiche Zeiteinheit (<= 1 Monat), ein Entwicklungszyklus ist immer
genau einen Sprint lang, ein Sprint wird nicht verkürzt oder verlängert (allerhöchstens
abgebrochen), am Ende eines Sprints steht ein fertiges Produkt (ggfs. mit geringer
Funktionalität).

22
Prüfungsvorbereitung MOS103_Informatik_I

87. Daily Scrum (wo bin ich hier?) (06_Software Entwicklung)

Jeden Tag wird ein Scrum Meeting mit allen Teammitgliedern abgehalten, max. 15
Minuten, im besten Fall stehend, folgende Fragen werden beantwortet:Was habe ich
gestern gemacht, was werde ich heute tun, wobei benötige ich Hilfe, was hindert
mich? Alle agilen Meetings finden in einer Timebox statt: Das Meeting endet, wenn
die geplante Zeit vorbei ist, nicht wenn das Meeting abgeschlossen ist!

88. Review (wo bin ich hier?) (06_Software Entwicklung)

Am Ende eines Sprints präsentiert das Team das Produkt (das nächste Produkt-
Inkrement). Zum Review sind alle Stakeholder und vor allem auch die Kunden
geladen. Präsentiert wird das Produkt, keine Folien über das Produkt. Ziel ist es, so
schnell wie möglich, zum richtigen Produkt zu finden!

89. Retroperspektive (wo bin ich hier?) (06_Software Entwicklung)

Am Ende eines jeden Sprints reflektiert das Team den zurückliegenden Sprint, was
hat gut funktioniert, wo gibt es Verbesserungspotential? Beschluss konkreter
Maßnahmen und Verantwortlichkeiten, um das Team und seine Arbeit zu
verbessern, wurden die Maßnahmen aus der letzten Retro umgesetzt?

90. Wer ist eigentlich dieses Team? (ja, wer eigentlich?) (und, vor allem, wozu?)

Im Scrum gibt es ein Entwicklungsteam für ein Produkt (Feature), das Team ist
selbstständig und cross-funktional aufgestellt, das Team kann ein Feature ohne Hilfe
von außen entwerfen, entwickeln, testen und deployen, alle notwendigen
Kompetenzen sind ausreichend im Team vorhanden, ein Team beginnt bei 2
EntwicklerInnen und sollte nicht mehr als 9-12 Mitglieder haben, das Team
entscheidet über die technische Umsetzung von Arbeiten, es schätzt den Aufwand,
der für Arbeiten anfällt.

91. Product Owner, a.k.a. der/die PO (wo bin ich hier?)

Ist alleine verantwortlich für das zu erstellende Produkt (Das Produkt kann ein
einzelnes Feature sein, z.B. die Suche bei Spotify), ist für die Außenkommunikation
verantwortlich, was muss das Produkt können, was haben wir gebaut? PO
beschreibt, was gemacht werden muss im Product Backlog, hat keinerlei Einfluss auf
das wie, d.h. die technische Umsetzung, priorisiert alle notwendigen Arbeiten

92. ScrumMaster (wo bin ich hier?)

Der Scrum Master ist der wandelnde Hygiene-Faktor der agilen Organisation, er
unterstützt das Team mit allem, was für eine effiziente Arbeitsweise notwendig ist, er
vertritt die agile Vorgehensweise in der Organisation und unterstützt Teams und PO
bei der Anwendung, er moderiert Review und Retroperspektive.

Das braucht niemand im Schiffbau, Informatik-Studenten erst ab 4. Semester

23
Prüfungsvorbereitung MOS103_Informatik_I

93. Produkt Backlog (wo bin ich hier?)

Das Produkt Backlog beinhaltet alle notwendigen Merkmale und Eigenschaften des
Produkts; in der Regel wird dies in der Form von User-Stories erledigt, der Umfang
einer User-Story sollte einen Sprint nicht überschreiten. Der PO und nur der PO
befüllt das Produkt Backlog und definiert die Reihenfolge (in jedem Sprint neu), das
Team schätzt den Umfang der Arbeiten und entscheidet wie viele User-Stories in den
nächsten Sprint übernommen werden.

94. Drei Bekannte Paradigmen der Programmierung (08_OOP_I)

Prozedurale Programmierung, Objekt-Orientierte Programmierung, Funktionale


Programmierung

94.1. Prozedurale Programmierung (Ergänzung)

Bei der prozeduralen Programmierung wird die Gesamtaufgabe, die eine Software
lösen soll, in kleinere Teilaufgaben aufgelöst. Jede Teilaufgabe für sich ist einfacher
zu beschreiben, programmieren und testen. Außerdem kann der entstehende
Programmcode in anderen Programmen wieder verwendet werden, ein sehr
wichtiger Aspekt in der Softwaretechnik. Die bei der Aufgabenlösung entstehenden
Programm-Module werden Prozeduren bzw. Funktionen genannt. Prozeduren und
Funktionen werden üblicherweise nach Aufgabengebieten gruppiert zu Bibliotheken
zusammengefasst, die dann verteilt und in beliebig viele andere Programme
eingebunden werden können. Typische prozedurale Programmiersprachen sind
beispielsweise Pascal, die Programmiersprachen C und BASIC; alle bereits recht
betagt. Modernere Programmiersprachen wie Java und C# betrachten den
prozeduralen Ansatz als veraltet und setzen stattdessen auf die Weiterentwicklung
zur objektorientierten Programmierung.

Skript (wo bin ich hier?): Prozedur a.k.a. Funktion, Teile und Herrsche (Teile die
Logik in einzelne Prozeduren / Funktionen, baue ein Hauptprogramm als
Aneinanderreihung von Funktionsaufrufen), keine Verbindung von Daten und
Verhalten des Codes.

94.2. Objekt-Orientierte Programmierung (Ergänzung)

Die objektorientierte Programmierung (OOP) ist eine Methode zur Modularisierung


von Programmen, die sich stark von der klassischen prozeduralen Programmierung
unterscheidet. Objektorientierte Software ist, wenn sie gut entworfen wurde, leichter
zu warten und zu erweitern als prozedurale. Zudem vereinfacht sie durch die strenge
Modularisierung Unit-Tests und Wiederverwendung von Softwareteilen. Sie folgt dem
Programmierparadigma der imperativen Programmierung. Bei der objektorientierten
Programmierung werden Programme in Einheiten unterteilt, die Objekte genannt
werden. Jedes Objekt besitzt einen Zustand, der durch dessen Eigenschaften
(Objektattribute) beschrieben wird. Nur die im Objekt selbst vorhandenen Funktionen
(Methoden genannt), können dessen Daten manipulieren und so den Zustand
verändern. Objekte können anderen Objekten Botschaften senden (indem sie deren
Methoden aufrufen) und sie damit auffordern, ihren Zustand zu ändern. Letztendlich
bleibt es aber dem Objekt selbst überlassen, ob es der Aufforderung nachkommt.

24
Prüfungsvorbereitung MOS103_Informatik_I

Somit befindet sich das Objekt immer in einem wohldefinierten, selbstkontrollierten


Zustand. Man fasst in der OOP-Programmierung also Daten und Funktionen zu
Objekten zusammen. Diese Objekte können auf vielfältige Weise miteinander in
Verbindung stehen, indem sie gegenseitig ihre Methoden aufrufen oder ein Objekt
andere Objekte enthält. So bilden die Objekte einer Software ein sehr flexibles
Gesamtsystem. Jedes Objekt gehört zu einer Klasse. Klassen werden auch oft als
Baupläne für Objekte beschrieben, weil sie definieren welche Attribute und Methoden
die dazugehörigen Objekte besitzen. Jedes Objekt ist eine Instanz seiner Klasse,
man sagt auch: Das Objekt "o" instanziiert die Klasse "k". Von einer Klasse kann es
beliebig viele Objekte geben, deren Eigenschaften sich unterscheiden können aber
nicht müssen. Objektorientierte Programme erfüllen verschiedene wichtige Kriterien,
die die Entwicklung vereinfachen, beschleunigen und gleichzeitig die Qualität
verbessern können:

• Datenkapselung: Die Daten eines Objekts können nicht unkontrolliert von


außen verändert werden, letztendlich entscheidet immer das Objekt selbst
über Änderungen seines Zustands.
• Austauschbarkeit: Objekte sind Abstraktionen realer Entitäten und Akteure,
die ihre tatsächliche Implementierung vor der Außenwelt verbergen und
dadurch austauschbar werden.
• Vererbung: Eigenschaften und Funktionen eines Objekts können an andere
Objekte weitergegeben und von diesen übernommen, verändert oder
überschrieben werden.
• Polymorphie unterstützt die Austauschbarkeit von Objekten, denn die gleiche
Nachricht kann an unterschiedliche Objekte gesendet werden und
dementsprechend unterschiedliche Aktionen bei diesen bewirken.

Nicht jede Programmiersprache unterstützt die objektorientierte Programmierung. C


und Pascal sind beispielsweise rein prozedural. Andere Sprachen wie C++ oder
Object Pascal erlauben OOP, erzwingen sie aber nicht. Die daraus resultierenden
Programme können eine Mischung aus verschiedenen Paradigmen sein. Das gleiche
gilt für Sprachen wie Hypertext Preprocessor (PHP) oder Perl, die durch
Erweiterungen OOP-fähig gemacht werden können. Weitere wie Eiffel, Smalltalk,
Java oder C# sind rein objektorientiert.

Skript (wo bin ich hier?): Verhalten und Daten sind an einer Stelle kombiniert,
Klassen dienen als Schablonen für ähnliches Verhalten und Daten, kein prozeduraler
Ablauf mehr, Objekte interagieren untereinander.

94.3. Funktionale Programmierung (Ergänzung)

Funktionale Programmierung ist ein deklaratives Programmierparadigma, bei dem


Programme als mathematische Funktionen formuliert werden. Während in
prozeduralen Programmiersprachen nacheinander Befehle ausgeführt und auf diese
Weise die Inhalte von Variablen verändert werden, hat in der funktionalen
Programmierung ein Ausdruck während der Laufzeit immer den gleichen Wert. Diese
Eigenschaft ist für einige akademische Anforderungen wie beispielsweise
Beweisführungen sehr hilfreich. Man unterscheidet rein funktionale
Programmiersprachen (z.B. Haskell und Miranda) von Programmiersprachen, die

25
Prüfungsvorbereitung MOS103_Informatik_I

das Programmierparadigma zwar aufnehmen aber mit imperativen Sprachelementen


vermischen (z.B. Scheme und Tcl).

95. Kapselung (08_OOP_I)

Objekt-Orientiertes Programmieren ermöglichen es, Informationen zu kapseln, d.h.


alle Daten und Verhalten, die zu einem bestimmten Objekt gehören, an einer Stelle
zu vereinen. Durch eine gute Kapselung ist dieses Objekt für sich selber funktional,
d.h. hat so wenige Abhängigkeiten wie möglich nach außen.

Ergänzung: Kapselung von Daten bedeutet, dass der Zugriff auf Eigenschaften nur
über Zugriffsmethoden erfolgen darf. Diese Methoden können Plausibilitätstests,
Datentypwandlungen oder beliebige Berechnungen enthalten, und sie (oder ,,nur''
sie) besitzen ,,Informationen'' über die eigentliche Implementierung.

96. Abstraktion (08_OOP_I)

Da wir eine Klasse als Schablone entwickeln, erreichen wir automatische eine
gewisse Abstraktion. Durch die Abstraktion können wir eine hohe
Wiederverwendbarkeit erreichen.

97. Abstrakter Datentyp, ADT (Ergänzung)

Ein ADT beschreibt, was die Operationen tun (Semantik), aber noch nicht, wie sie es
tun sollen (Implementierung). Auch kann das Konzept des ADTs unterschiedlich
spezifiziert und ein ADT auf verschiedene Weise notiert werden, bspw. Durch
Pseudocode oder durch eine mathematische Beschreibung. Modernere
Programmiersprachen unterstützen allerdings gezielt die Erstellung von ADTs.
Objektorientierte Programmiersprachen unterstützen durch ihr Klassenkonzept die
Erstellung von ADTs, da hier Daten und Operationen gebunden werden, die Daten
geschützt und die zulässigen Operationen festgelegt werden können. Einige
modulare Programmiersprachen wie Ada oder Modula-2 unterstützen ebenfalls
gezielt die Erstellung von ADTs. In der Regel ist es möglich, einen ADT durch
Definition der Daten und der Signaturen der Operationen festzulegen, während die
Semantik als Kommentartext beschrieben wird.

98. Alles in Python ist ein Objekt! (08_OOP_I)


➢ Das bedeutet: Auch Integer (Int) ist eine Klasse und damit ein Objekt
➢ Die Ganzzahl 2 ist eine Instanz der Klasse Int.
➢ (die Klasse kennt nicht die Daten, aber die Datenstruktur der Instanzen)
➢ __add__ ist eine Methode der Klasse int
➢ An Stelle von 2+3 funktioniert auch a=2, b=3, c=int.__add__(a,b)
➢ die Klasse kennt alle Methoden für die Instanzen der Klasse

99. Klasse (08_OOP_I)

Eine Klasse ist eine Schablone für die Erzeugung von Instanzen, sie kennt die
Datenstruktur (nicht die konkreten) Daten für Instanzen, sie kennt das Verhalten (die
Methoden/Funktionen) für alle Instanzen der Klasse; auch eine Klasse ist ein Objekt
class Spielfeld:

26
Prüfungsvorbereitung MOS103_Informatik_I

breite = 10
laenge = 10
Die Klasse ist ein Objekt

100. Instanz (08_OOP_I)

Aus einer Klasse werden Instanzen erzeugt, die Instanz hat die Klasse als Typ, die
Instanz ist das konkrete, nutzbarere Objekt, z.B.: U-Boot Instanz der Klasse Schiff.
ein_spielfeld = Spielfeld()
ein_spielfeld.breite
Die Instanz ist ein Objekt
class Vector():
def __init__(self,x,y,z):
self.x=x
self.y=y
self.z=z
def betrag(self):
return self.x**2+self.y**2+self.z**2
v1 = Vector(2,3,4)
absv1 =v1.betrag()
print(absv1)
>>> type(Vector)
<class 'type'>
>>> type(v1)
<class '__main__.Vector'>
>>> type(absv1)
<class 'int'>

101. Klasse II (08_OOP_I)

Werte, die direkt der Klasse zugeordnet werden, sind Klassen-Attribute. Aus einer
Klasse können beliebig viele Instanzen gebaut werden. Die Klassen-Attribute der
Klasse sind für alle Instanzen gleich, da sie an die Klasse gebunden sind.
class Spielfeld:
breite = 10 # alle Instanzen (Spielfelder) haben die
laenge = 10 # Breite 10 und die Länge 10
def berechne_anzahl_felder(self):
return Spielfeld.breite*Spielfeld.laenge

102. Methode (08_OOP_I)

Die Methode ist eine an eine Klasse gebundene Funktion. Genau wie bei der
Funktion können wir Parameter übergeben und ein Return Statement verwenden.
Die Methode kann auf die Attribute der Klasse zugreifen. Die Klasse definiert (in der
Regel) die Methoden für alle Instanzen.

103. Instanzattribute (08_OOP_I)

Bisher haben alle Instanzen der Klasse Spielfeld die gleiche Breite und Länge. Damit
Instanzen unterschiedlich sein können, benötigen wir Instanz-Attribute. Ziel ist es,

27
Prüfungsvorbereitung MOS103_Informatik_I

dass für jede Instanz ein anderes Spielfeld (mit der gleichen Größe) gespeichert
werden kann.
Die Größe ist also kein Instanzattribut, sondern ein Klassenattribut, d.h. gleich groß
für alle Instanzen der Klasse Spielfeld. Beispiele für Instanzattribute sind der Name
oder die Farbe des Spielfeldes, da sich diese Eigenschaften je Spielfeld voneinander
unterscheiden.
Man bezeichnet Instanzattribute deshalb als ,,nicht-statisch'' oder ,,dynamisch'', da
sie für jede Instanz einer Klasse dynamisch erstellt werden (und sich deshalb von
denen anderer Instanzen unterschieden).
import numpy as np
class Spielfeld:
breite = 10
laenge = 10
def __init__(self):
"""Konstruktor: Erzeugt ein Feld"""
self.feld = np.zeros((Spielfeld.breite, Spielfeld.laenge))
def berechne_anzahl_felder(self):
"""Gibt die Groe des Felds zuruck"""
return self.feld.size

104. Konstruktor (08_OOP_I)

Der Konstruktor ist eine Methode, über die jede Klasse verfügt. Der Konstruktor wird
immer aufgerufen, wenn eine neue Instanz von einer Klasse erzeugt wird (bisher
wurde immer der default-Konstruktor aufgerufen, daher musste er nicht implementiert
werden). Der Konstruktor muss nicht explizit angesprochen werden. Er ist direkt mit
Klassenname() verbunden. Daher muss der Konstruktor auch jedes Mal den gleichen
Namen haben.

105. Konstruktor (Ergänzung)

Der Konstruktor wird in Python durch die Kopfzeile „def __init__(self):“ definiert. Es
handelt sich hierbei um eine spezielle private Methode, die von außen nicht direkt
aufgerufen werden kann, sondern nur automatisch beim Erzeugen eines neuen
Objekts aufgerufen wird. Wie alle anderen Methoden erhält auch der Konstruktor als
ersten Parameter (self) eine Referenz auf das zugehörige Objekt. Im Rumpf des
Konstruktors müssen alle Instanzattribute der Klasse angelegt werden. Da diese
Attribute zum gerade erzeugten Objekt gehören und dieses mit „self“ referenziert wird,
ist den Namen der Instanzattribute xxx jeweils „self.“ Voranzustellen, d.h. das Attribut
wird mit self.xxx bezeichnet.

106. Self (08_OOP_I)

Self ist ein Platzhalter/Referenz für die konkrete Instanz. Zum Zeitpunkt der
Klassendefinition sind die Instanzen noch nicht bekannt. Dennoch ist es notwendig,
Methoden zu implementieren, die auf Instanzen zugreifen können. Dies ist über self
möglich (in JAVA als „this“ bekannt).
class self_beispiel():
def gib_self_id(self):

28
Prüfungsvorbereitung MOS103_Informatik_I

return id(self)

107. Dokumentation von Klassen (08_OOP_I)

Klassen müssen, ebenso wie Funktionen, sauber dokumentiert werden. Die Notation
ist äquivalent, Beginn und Ende der Dokumentation werden mit """ bezeichnet.
class Spielfeld:
"""
Ein Spielfeld fuer Schiffe versenken
Das Spielfeld kann ueber Breite und…
….
"""

108. Python ist dynamisch (08_OOP_I) (Java auch)

Wir können Attribute auch zur Laufzeit des Programmes hinzufügen. Attribute
werden per einfacher Zuweisung erzeugt.
ein_spielfeld.name = 'Das erste Spielfeld'
ein_spielfeld.name
noch_ein_spielfeld.name

109. Erklären Sie den Zusammenhang zwischen Klasse, Objekt und Instanz
(09_OOP_II)

Eine Klasse ist eine Schablone für die Erzeugung von Instanzen. Sie kennt die
Datenstruktur (nicht die konkreten) Daten für Instanzen. Sie kennt das Verhalten (die
Methoden) für alle Instanzen der Klasse. Auch eine Klasse ist ein Objekt. Werte, die
direkt der Klasse zugeordnet werden, sind Klassen-Attribute. Diese Attribute gelten
dann für alle Instanzen der Klasse. Möchte man Instanzattribute erzeugen muss ein
selbst definierter Konstruktor (ist eine spezielle Methode) erstellt werden. Der
Konstruktor weist den Instanzattributen Werte zu. Aus einer Klasse können beliebig
viele Instanzen gebaut werden.
Objekt: Alles in Python ist ein Objekt
Instanz: Aus einer Klasse werden Instanzen erzeugt. Die Instanz hat die Klasse als
Typ. Die Instanz ist das konkrete, nutzbare Objekt, z.B. U-Boot ist eine Instanz der
Klasse Schiff. Die Instanz ist selbstverständlich auch ein Objekt

110. Was übergeben Sie mit self? (09_OOP_II)

Self ist die Referenz auf das zugehörige Objekt.

Self ist KEIN Parameter in der Zeile der Klassendefinition def class(self):

111. Starke Kohäsion und lose Kopplung (09_OOP_II)

Ziel ist es, Logik in einzelnen Klassen zu kapseln, Teile und Herrsche Ansatz wie
bei der prozeduralen Programmierung mit Funktionen (? Bekannt für die Teilung von
Argumenten („teile“), durch die die Anwendung des - ansonsten gleichen – Codes

29
Prüfungsvorbereitung MOS103_Informatik_I

auf weniger Argumente sehr schnell ausgeführt werden kann („herrsche“), die
einzelnen Ergebnisse nach der Teilung müssen dann wieder zusammengesetzt
werden), eine Klasse sollte in sich so kohärent wie möglich sein, d.h. die Klasse
beschreibt alles was sie modelliert vollständig und korrekt.
Die Kopplung zu anderen Klassen wiederum ist so lose wie möglich. Es werden
möglichst wenig zusätzlich Elemente benötigt, um mit der Klasse sinnig arbeiten zu
können.

112. Klassendiagramm (09_OOP_II)

Im Gegensatz zum Aktivitätsdiagramm handelt es sich um ein Strukturdiagramm. Mit


Hilfe von welchen Klassen soll ein Problem modelliert werden? Über welche Attribute
und Methoden verfügen die Klassen? In welchem Zusammenhang stehen die
Klassen miteinander?

113. Wie weit würden wir ohne ein Klassendiagramm kommen? (09_OOP_II)

Ja, wie weit eigentlich?

Das Aktivitätsdiagramm (Was jetzt? Klassendiagramm oder Aktivitätsdiagramm?)


kann alle prozeduralen Abläufe darstellen. Ohne Diagramm sind Kreativität,
Überlegen und Übersicht gefordert.

In der Objektorientierung haben wir aber nicht notwendigerweise prozedurale


Abläufe. Oh Schreck, was nun?

114. Beispiele für die Klassen Spielfeld und Modul (09_OOP_II)

Die Attribute breite, laenge, feld …sind public (+), die Attribute name, ects und sws
sind protected (#)

115. Zugriff auf Attribute (09_OOP_II)


➢ Public: im Klassendiagramm über ein + symbolisiert, jeder Teil des Programmes
darf auf das Attribut zugreifen
Das bedeutet, dass der Wert des Attributes auch von außen verändert werden
kann.

30
Prüfungsvorbereitung MOS103_Informatik_I

➢ Protected: im Klassendiagramm über ein # symbolisiert, nur die eigene Klasse


(und ihre Instanzen) dürfen auf das Attribut zugreifen. Um sicheren Code zu
ermöglichen, ist der Zugriff von außen nicht möglich
Das bedeutet: Mit Getter/Setter und @property-Decorator arbeiten. Geschütztes
Attribut ist am Unterstrich vor dem Attributnamen erkennbar.

116. Implementierung der Klasse Modul mit public Instanz-Attributen

>>> class Modul():


... def __init__(self, name, ects, sws):
... self.name = name # name ist public
... self.ects = ects # ects ist public
... self.sws = sws # sws ist public
... def veroeffentliche_modul(self):
... return self.name + ' erhaelt '+ str(self.ects) +' ECTS bei '+ str(self.sws*12) + '
Praesizeit'
...
>>> informatik_ii = Modul('M3', 5, 4)
>>> informatik_ii.veroeffentliche_modul()
'M3 erhaelt 5 ECTS bei 48 Praesizeit'
>>>
>>> def schlecht_implementierte_benutzer_oberflaeche(ein_modul):
... ects = input('Wieviele ECTS sollen es denn werden?')
... ein_modul.ects = ects # ects wird überschrieben
... print(ein_modul.veroeffentliche_modul())
...
>>> schlecht_implementierte_benutzer_oberflaeche(informatik_ii)
Wieviele ECTS sollen es denn werden?10
M3 erhaelt 10 ECTS bei 48 Praesizeit

Die Implementierung ist nicht zufriedenstellend, weil von außen auf ects
zugegriffen werden kann.

117. Setter (09_OOP_II)

Solange das Attribut von außen zugänglich ist, besteht z.B. die Gefahr, dass
ungültige Werte eingetragen werden. Das Attribut wird daher von uns “versteckt”
bzw. auf protected gesetzt. Zugriff ist jetzt nur noch über die Setter-Methode
möglich (technisch ist der Zugriff in Python weiterhin möglich, der Unterstrich ist aber
für jeden Programmierer ein rotes Tuch).
Ändere dazu „self.ects = ects“ in „self._ects = ects“ (Unterstrich vor ects)
def set_ects(self, value): # Hier haben wir einen Setter definiert!!!
try:
value = int(value)
self._ects = value
except:
print('Kein gueltiger Wert fur ECTS')
(ändere auch für die Ausgabe „self.ects“ in „self._ects“)

31
Prüfungsvorbereitung MOS103_Informatik_I

Das Setzen der ECTS erfolgt jetzt an Stelle „self.ects=ects“ (weil Attribut)
durch „modulname.set_ects(ects)“ (weil Methode). Die Änderung alleine
verhindert den Zugriff von außen nocht nicht.

Gleiches Vorgehen bei den Semesterwochenstunden (bzw. selbststudium)


self._sws=sws
def set_sws(self, value):
try:
value = int(value)
self._sws = value
except:
print('Kein gueltiger Wert fur SWS')
(ändere auch für die Ausgabe „self.sws“ in „self._sws“)

Anzahl der Stunden für das Selbststudium als Getter, bestimmt aus
(bekannten) ects und sws:
Wegfall des Attributs selbststudium im Konstruktor
Keine Definition als setter
Definition als Getter:
def get_selbststudium(self):
return self._ects*30-self._sws*12
Ausgabe mit str(self.get_selbststudium()), Klammerpaar () nicht vergessen

Anzahl der ects als Getter (bei existierendem Setter):


def set_ects(self, value):
try:
value = int(value)
self._ects = value
except:
print('Kein gueltiger Wert fur ECTS')
def get_ects(self) # ohne value!
return self.ects

118. Getter (09_OOP_II)

Wenn wir keinen direkten schreibenden Zugriff von außen zulassen wollen, sollte es
auch keinen lesenden geben. Im konkreten Beispiel haben wir den Getter benutzt,
um die Logik der Klasse umzusetzen.
In der Regel wird jedes Attribut einen Getter und einen Setter besitzen.

119. Was ist der Nachteil der klassischen Getter / Setter (09_OOP_II)

Um die neuen getter / setter einzusetzen, muss der Aufruf angepasst werden.

➢ Vorher: Modul.ects
➢ Nachher: Modul.get_ects()
d.h. aller Code der auf ECTS zugreift muss angepasst werden, obwohl lediglich die
Interna der Klasse geändert wurden
(das widerspricht der Idee von starker Kohäsion und loser Kopplung!).

32
Prüfungsvorbereitung MOS103_Informatik_I

120. Decorator

Ziel ist es für ein Attribut getter und setter Methoden zu implementieren, den Aufruf
aber unverändert zu zulassen.
➢ d.h. für get und set kann immer noch Modul.ects verwendet werden!
➢ In gleicher Art und Weise sollen die Attribute als protected gesetzt werden
können.
➢ Eine Decorator kann verwendet werden, um Methoden zu erweitern
➢ Für Getter und Setter wenden wir @property und @name.setter an

121. Beispiel für einen Decorator (leistung_in_ps)

class Motor():
def __init__(self, leistung_in_ps, art):
self.leistung_in_ps = leistung_in_ps # leistung ohne Unterstrich (identisch)
self.art = art

@property # @property decorator


def leistung_in_ps(self):
return self._leistung_in_ps # leitet den Getter ein
# return im Setter, weil mit dem Getter ein Wert geholt wird!

@leistung_in_ps.setter # Setter (@methodname.setter)


def leistung_in_ps(self, value): # Methodenname gleich
self._leistung_in_ps = value
# natürlich kein return im Setter, weil nur gesetzt wird!

Aufruf: tesla_motor.leistung_in_ps = 500 # ruft setter auf, Wert angeben


tesla_motor.leistung_in_ps # ruft getter auf

122. Getter und Setter über den Decorator

➢ Der @property Decorator leitet den Getter ein


➢ Der @name.setter Decorator leitet den Setter ein, hier muss ein Wert
übergeben werden
➢ Nur wenn die Decorator verwendet werden, dürfen zwei Methoden mit dem
gleichen Namen in Python existieren
➢ In der Regel sollten Sie getter UND setter implementieren, um fehlerfreie
Funktionalität sicherzustellen
➢ Attribute, die über @property eingerichtet werden, müssen immer auf
protected Attributen agieren!
o d.h. im Setter und Getter mit Unterstrich
o aber im Konstruktor ohne Unterstrich

123. Einschub zum Decorator als Getter

Im allgemeinen Fall wird der Decorator für eine Methode geschrieben, deren
Rückgabeverhalten modifiziert (dekoriert) werden soll (Messung der Laufzeit, keine
Division mit Null, was auch immer…). Dafür muss der Decorator definiert werden.
Beispiel 1:

33
Prüfungsvorbereitung MOS103_Informatik_I

def prevent_from_nonsense(func):
def inner(x,y):
if y==0:
return "pass auf den Nenner auf"
return func(x,y)
return inner
@prevent_from_nonsense
def div(a,b):
return a/b

Beispiel 2:
def str_upper(Funktion):
def inner():
return Funktion().upper()
return inner
@str_upper
def demotext():
return "hello world"
print(demotext()) ➔ HELLO WORLD

Der property decorator ist built-in, d.h.wird nur gesetzt, aber nicht definiert.
@property # @property decorator
def leistung_in_ps(self):
return self._leistung_in_ps # leitet den Getter ein
Er gibt also keine modifizierten Werte zurück, die Dekoration besteht
➢ in der durchgehend gleichen Verwendung des Wertes der Methode, auch in
anderen Methoden der Klasse
➢ und damit im Schutz.

Fazit
Es genügt das folgende Schema:
@property
def name(self):
return self._name
@name.setter
def name(self, wert)
self._name = wert

Was bedeutet property(**()) für get, set, del und doc?


@def foo():
doc = "The property."
def fget(self):
return self._
def fset(self, value):
self._ = value
def fdel(self):
del self._
return locals()
= property(**())

34
Prüfungsvorbereitung MOS103_Informatik_I

124. Aktivitätsdiagramm WHILE

➢ Zähler-kontrollierte Schleifen
Ein Programmkonstrukt, mit dem der Schleifenkörper unter der Kontrolle einer
Zählervariablen eine bestimmte Anzahl von Malen durchlaufen wird. Dies
entspricht der for-Schleife, wie wir sie in C bzw. C++ vorfinden. Python kennt
diesen Schleifentyp nicht: for (i=0; i <= n; i++)
➢ Bedingungs-kontrollierte Schleifen
Eine Schleife wird solange wiederholt, bis sich eine Bedingung ändert, also
solange eine Bedingung z.B. wahr ist. Es gibt while-Schleifen und Do-While-
Schleifen, die dieses Verhalten haben.
➢ Sammlung-kontrollierte Schleifen
Mit Sammlung meinen wir Listen, Arrays oder sonstige Anordnungen von
Objekten. Über die Elemente einer solchen Sammlung wird mittels einer Schleife
iteriert. Diese Schleifen werden meistens eingeleitet mit dem Schlüsselwort
"foreach", aber auch mit "for" wie in Python.

125. Aktivitätsdiagramm WHILE mit ELSE

35
Prüfungsvorbereitung MOS103_Informatik_I

Wie auch die bedingte if-Anweisung hat die while-Schleife in Python im Gegensatz
zu anderen Programmiersprachen einen optionalen else-Zweig, was für viele
Programmierer gewöhnungsbedürftig ist. Die Anweisungen im else-Teil werden
ausgeführt, sobald die Bedingung nicht mehr erfüllt ist. Sicherlich fragen sich einige
nun, worin dann der Unterschied zu einer normalen while-Schleife liegt. Hätte man
die Anweisungen nicht in den else-Teil gesteckt, sondern einfach hinter die while-
Schleife gestellt, wären sie ja auch genauso ausgeführt worden. Es wird erst mit
einem break-Kommando, was wir später kennenlernen sinnvoll.

126. Aktivitätsdiagramm WHILE mit BREAK und ELSE

Normalerweise wird eine while-Schleife nur beendet, wenn die Bedingung im


Schleifenkopf nicht mehr erfüllt ist. Mit break kann man aber eine Schleife vorzeitig
komplett verlassen. Mit 'continue' beendet man lediglich einen Durchlauf, d.h. man
kehrt zum Schleifenkopf, also zur Überprüfung der Bedingung, zurück.

127. FOR-Schleife

Wie auch die while-Schleife ist die for-Schleife eine Kontrollstruktur, mit der eine
Gruppe von Anweisungen (ein Block) wiederholt ausführt werden kann. Sowohl
Syntax als auch Semantik der For-Schleifen unterscheiden sich in den
verschiedenen Programmiersprachen. Die "klassische" numerische Schleife besitzt
eine Schleifenvariable, die mit einem Startwert initialisiert wird und nach jedem
Durchlauf des Schleifenkörpers verändert wird, bis der definierte Zielwert erreicht ist
(Zählschleife). Die in Python benutzte Art von For-Schleife entspricht der in der Bash-
Shell oder in Perl verwendeten foreach-Schleife. Bei dieser Schleifenart handelt es
sich um ein Sprachkonstrukt mit dessen Hilfe nacheinander die Elemente einer
Menge oder Liste bearbeitet werden können. Dazu werden sie einer Variablen
zugewiesen. In Python wird die Zählschleife mit der range()-Funktion realisiert.
range() liefert einen Iterator, der Zahlen in einem bestimmten Bereich (range) bei
Bedarf liefern kann.
range() kann aber auch mit zwei Argumenten aufgerufen werden. Dann wird ein
Iterator für alle ganzen Zahlen von begin (einschließlich) bis end (ausschließlich)
geliefert. Mit einem optionalen dritten Argument kann man range() noch die
Schrittweite mitgeben. range(begin,end,schritt) kann auch als Ausdruck verwendet
werden, z.B. liefert sum(range(100) den Wert 5050.

36
Prüfungsvorbereitung MOS103_Informatik_I

128. Maximum von 3 Zahlen, Aktivitätsdiagramm und Code

def max_of_three_numbers(x,y,z):
if x>y:
if x>z:
maxi=x
else:
maxi=z
else:
if y>z:
maxi=y
else:
maxi=z
return maxi

x=31
y=55
z=7
print("das Maximum von ",x," ,",y," und ",z," lautet: ",max_of_three_numbers(x,y,z))

129. Summenbildung mit WHILE, Aktivitätsdiagramm und Code

def summe_mit_while(n):
if n<0:
raise Warning("Geben Sie eine positive Zahl ein")

37
Prüfungsvorbereitung MOS103_Informatik_I

elif type(n)!=int:
raise Warning("Geben Sie eine Integerzahl ein")
else:
summe=0
i=0
while i<= n:
summe +=i
i+=1
return summe

n=100
print("die Summe 1 bis ",n," ergibt ",summe_mit_while(n))

130. Sieb des Erastosthenes, Beschreibung (Prinzip) und Code

def eratosthenes(obergrenze):
global zahlen # dann braucht zahlen nicht zurueckgegeben
werden
zahlen = [True]*(obergrenze+1) # liste mit Elementen "True"
zahlen[0] = False # 0 ist nicht prim
zahlen[1] = False # 1 ist nicht prim

i=2 # beginne bei i=2


while i*i <= obergrenze: # Suche nur bis Wurzel(Obergrenze+1)
if zahlen[i] == True: # Wenn i Primzahl ist:
for k in range(i*i,obergrenze+1,i): # von i*i in Schritten von i
zahlen[k] = False # streiche die Vielfachen von i
i = i+1 # next i

# Ausgabe aller gefundenen Zahlen


for i in range(obergrenze+1):
if zahlen[i] == True:
print(i, 'ist prim.')

return None

38
Prüfungsvorbereitung MOS103_Informatik_I

eratosthenes(10)
print(zahlen)

131. Fibonacci Reihe, Code

fib = [1,1]
i_end=15
for i in range(2,i_end):
fib.append(fib[i-2]+fib[i-1])

fib
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

132. Umrechnungstabelle

Erstellen Sie eine Umrechnungstabelle, die den Bereich vo


n 10m/s bis 50m/s in 5m/s Schritten abdeckt und die passende km/h Geschwindikeit
angibt.
print("------------------")
print("| [m/s] | [km/h] |")
print("------------------")
for v in range (10,50,5):
print("| ",v," | ", '%4.0f' %int(3.6*v)," |")
print("------------------")
------------------
| [m/s] | [km/h] |
------------------
| 10 | 36 |
| 15 | 54 |
| 20 | 72 |
| 25 | 90 |
| 30 | 108 |
| 35 | 126 |
| 40 | 144 |
| 45 | 162 |

133. Schaltjahr

Schaltjahr liegt vor, wenn die Jahreszahl ohne Rest durch 4 teilbar ist
Es gilt jedoch folgende Ausnahme:
Wenn die Jahreszahl ohne Rest durch 100 teilbar ist, dann ist es kein Schaltjahr
Für diese Ausnahme gilt wiederum die folgende Ausnahme
Wenn die Jahreszahl ohne Rest durch 400 teilbar ist, dann ist es doch ein Schaltjahr
x = [1600, 1700, 1800, 1900, 2000, 2001]
for jahr in x:
# print("Jahr: ",jahr)
j_vier = jahr%4
j_hundert = jahr%100
j_vierhundert = jahr%400
if(j_vierhundert ==0):

39
Prüfungsvorbereitung MOS103_Informatik_I

print("Das Jahr ", jahr," ist ein Schaltjahr")


continue
if(j_vier==0 and j_hundert ==0):
print("Das Jahr ", jahr," ist ein kein Schaltjahr")
continue
if(j_vier==0 and j_hundert !=0):
print("Das Jahr ", jahr," ist ein ein Schaltjahr")
continue
Das Jahr 1600 ist ein Schaltjahr
Das Jahr 1700 ist ein kein Schaltjahr
Das Jahr 1800 ist ein kein Schaltjahr
Das Jahr 1900 ist ein kein Schaltjahr
Das Jahr 2000 ist ein Schaltjahr

134. Quadratische Gleichung

from math import sqrt


def loese_p_q(p,q):
if p*p/4-q < 0:
print('es gibt zwei komplexe Loesungen')
print('x_1 = -p/2 + sqrt(q-p*p/4)*i')
print(' = ', -p/2 + sqrt(q-p*p/4),'*i')
print('x_2 = -p/2 - sqrt(q-p*p/4)*i')
print(' = ', -p/2 - sqrt(q-p*p/4),'*i')
elif p*p/4-q == 0:
print('es gibt eine reelle Loesung')
print('x = -p/2')
print(' = ',-p/2)
else:
print('es gibt zwei reelle Loesungen')
print('x_1 = -p/2 + sqrt(p*p/4-q)')
print(' = ',-p/2 + sqrt(p*p/4-q))
print('x_2 = -p/2 - sqrt(p*p/4-q)')
print(' = ',-p/2 - sqrt(p*p/4-q))
# break
loese_p_q(3, 1)

135. Russische Bauernmultiplikation

def halbiere_und_runde_ab(mult1):
return int(mult1/2)
def verdopple(mult2):
return 2*mult2
def ist_gerade(zahl):
return(zahl%2==0)

def russische_multiplikation(multiplikator,multiplikand):
result=0
while multiplikator > 1:
multiplikator = halbiere_und_runde_ab(multiplikator)

40
Prüfungsvorbereitung MOS103_Informatik_I

multiplikand = verdopple(multiplikand)
if(ist_gerade(multiplikator)):
continue
else:
result=result+multiplikand
print(multiplikator,multiplikand,result)
return result

multiplikator = 222
multiplikand = 333
result=73926
print(result == russische_multiplikation(multiplikator,multiplikand))

111 666 666


55 1332 1998
27 2664 4662
13 5328 9990
3 21312 31302
1 42624 73926
True

136. Direkte Berechnung der n-ten Fibonacci Zahl

from math import sqrt


def fibo(n):
h1=sqrt(5)
h2=(1+h1)/2
h3=(1-h1)/2
return int((pow(h2,n)-pow(h3,n))/h1)

for _ in range(101):
print(_,fibo(_))

137. Iterative Berechnung der Wurzel einer Zahl, Diagramm und Code

def iterative_root(x):
start=0.1*float(x)
eps=1E-15
neu=(start+x/start)/2
print("start= ",start," neu= ",neu)
print("abs(start-neu)= ",abs(start-neu))
print(abs(start-neu)<=eps)
while abs(start-neu)>=eps:
start = neu

41
Prüfungsvorbereitung MOS103_Informatik_I

neu = (start+x/start)/2
print("start= ",start," neu= ",neu)
return neu

x=2
print("Wurzel aus ",x, " ist: ",iterative_root(x))

138. Pythogoräische Zahlen

Drei natürliche Zahlen, welche die Gleichung a2+b2=c2 erfüllen, heißen


pythagoräische Zahlen.

from math import sqrt


n = int(input("Maximale Zahl? "))
for a in range(1,n+1):
for b in range(a,n):
c_square = a**2 + b**2
c = int(sqrt(c_square)) # das ist der Nachkomma-Anteil von c
if ((c_square - c**2) == 0): # Integer, wenn c keinen Nachkomma-Anteil hat
print(a, b, c)

139. Umwandlung dezimal nach binär, Aktivitätsdiagramm und Code

def dec2bin(n):
global bin_array
if n==0:
return [0]
else:
quotient=n
bin_array=[]

42
Prüfungsvorbereitung MOS103_Informatik_I

while quotient!=0:
quotient=int(n/2)
rest=int(n%2)
bin_array.append(rest)
n=int(quotient)
rev= bin_array[::-1]
return rev

a=10
b=dec2bin(a)
print("dezimal ",a, "entspricht binaer ",b)

140. Quersumme, Aktivitätsdiagramm und Code

def quersumme(numb):
quer=0

43
Prüfungsvorbereitung MOS103_Informatik_I

while numb > 0:


quer = quer + numb%10
numb = numb // 10
return quer
print(quersumme(123456789))

141. Berechnung des Ostersonntagtermines

Die Kirchenrechnung (computus ecclesiasticus) war eine der wichtigsten Anwendung


der Arithmetik im Mittelalter. Ostern findet seit dem Konzil in Nicäa (325) immer am
Sonntag nach dem ersten Vollmond statt, der auf den 21. März folgt (Tag - und
Nachtgleiche). Ein relativ einfacher Algorithmus:

k = Jahr / 100 –Jahr / 400 –1 k –1 ist Differenz julianisch und gregorianisch


M = 16 + k – (Jahr / 100 * 8 + 13) / 25 M –1 = säkulare Mondschaltung
H = Jahr MOD 19 Mondparameter (H +1= Goldene Zahl)
A = (M + H * 19) MOD 30 Anzahl Tage ab 21. März bis Vollmond
T = (A + H / 11) / 29 für Osterausnahmen 1954, 1981, 2049, …
B = 120 + A – T Osterkennzahl 120 für 27. März
C = ( B + Jahr + Jahr / 4 – k ) MOD 7 Wochentag Ostervollmond
E= B–C E Osterkennzahl (Easter index)
Ostersonntag = 1 + E MOD 31
Ostermonat = E / 31

def ostersonntag(self):
k = self//100 - self//400 +1
m = 16+k -(self//100 *8 +13) //25
h = self%19
a = (m+h*19)%30
t = (a+h//11)//29
b = 120+a-t
c = (b+self+self//4 -k)%7
e = b-c
tag = 1+e%31
monat =e//31
# print("k=",k,"m=",m,"h=",h,"a=",a,"t=",t,"b=",b,"c=",c,"e=",e)
print("Der Ostersonntag des Jahres",self,"faellt auf den",tag,".",monat,".")

for _ in range(2018,2026):
ostersonntag(_)

142. Ulam-Folge oder das 3n + 1 Problem

Der Name der Ulam-Folge geht auf den polnischen Mathematiker Stanislaw Ulam
zurück. Ist die Startzahl gerade, so ist sie zu halbieren, sonst zu verdreifachen und
um 1 zu erhöhen (daher 3n+1- Problem).

def ulam(start,anzahl):
global ausgabe
ausgabe = []

44
Prüfungsvorbereitung MOS103_Informatik_I

i=0
while i<anzahl:
if start%2 ==0:
start=start//2
ausgabe.append(start)
i+=1
else:
start=3*start+1
ausgabe.append(start)
i+=1
return ausgabe

ulam(100,30)
print(ausgabe)
[50, 25, 76, 38, 19, 58, 29, 88, 44, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4,
2, 1, 4, 2, 1, 4, 2]
Sobald eine Potenz von 2 erreicht wird, ist die Folge periodisch (4,2,1,4,2,1,4,2,1…)

45