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++.
^ ist die XOR Funktion, 3^8=11 (0011 XOR 0100), 3^10=9 (0011 XOR 1010)
// (3/2=1.5, 3//2=1)
Teile von Libraries: from math import pi, from math import e, …(sin, cos, tan..)
➢ 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)
2
Prüfungsvorbereitung MOS103_Informatik_I
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
Jedes Objekt hat eine ID, Abfrage: id(pi), jedes Objekt hat einen Typen, Abfrage:
type(pi)
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.
(veränderliche_variable = 1, _unveränderliche_variable = 1)
from math import sin, type(sin), builtin_function_or_method, sin hat eine id!
3
Prüfungsvorbereitung MOS103_Informatik_I
Alle Ganzzahligen Zahlen, auch negative Werte und die Null, eignen sich
hervorragend zum Zählen / Iterieren, lassen sich gut vergleichen (im Vergleich zu
Floats)
Gleitkommazahlen (3,142; 0.1; -2,5), normiert in der IEEE 754 Double Precision
Text bzw. Aneinanderreihung von Zeichen, innerhalb Anführungszeichen („“ oder ‚‘)
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
Das Intervall darf nicht 0 sein: x[::0] ergibt eine ValueError (slice stp cannot be zero)
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
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)
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]
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.
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.
# 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
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]
➢ 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
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
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.
Vergleich zweier Variablen miteinander (Arität = 2), Verschiedene Typen können als
Operanden verwendet werden, das Ergebnis ist immer vom Typ Boolean
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)
7
Prüfungsvorbereitung MOS103_Informatik_I
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)
47. XOR (^) in Python am Beispiel 7^10 (binär: 0111 ^ 1010) (03_ Rel. & Log. Op)
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
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.
Ü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.
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)
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.
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
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
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:
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.
Führe den Code aus, solange die Bedingung True ist, das Else wird nur ausgeführt,
wenn die Bedingung von While False ist
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)
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
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
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.
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.
“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
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.
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)
15
Prüfungsvorbereitung MOS103_Informatik_I
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.
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
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)
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.
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
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!')
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 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
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
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
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
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
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!
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
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
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.
21
Prüfungsvorbereitung MOS103_Informatik_I
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.)
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
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!
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!
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.
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
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.
23
Prüfungsvorbereitung MOS103_Informatik_I
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.
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.
24
Prüfungsvorbereitung MOS103_Informatik_I
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.
25
Prüfungsvorbereitung MOS103_Informatik_I
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.
Da wir eine Klasse als Schablone entwickeln, erreichen wir automatische eine
gewisse Abstraktion. Durch die Abstraktion können wir eine hohe
Wiederverwendbarkeit erreichen.
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.
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
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'>
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
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.
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
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.
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.
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)
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…
….
"""
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
Self ist KEIN Parameter in der Zeile der Klassendefinition def class(self):
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.
113. Wie weit würden wir ohne ein Klassendiagramm kommen? (09_OOP_II)
Die Attribute breite, laenge, feld …sind public (+), die Attribute name, ects und sws
sind protected (#)
30
Prüfungsvorbereitung MOS103_Informatik_I
Die Implementierung ist nicht zufriedenstellend, weil von außen auf ects
zugegriffen werden kann.
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.
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
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
class Motor():
def __init__(self, leistung_in_ps, art):
self.leistung_in_ps = leistung_in_ps # leistung ohne Unterstrich (identisch)
self.art = art
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
34
Prüfungsvorbereitung MOS103_Informatik_I
➢ 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.
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.
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
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))
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))
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
return None
38
Prüfungsvorbereitung MOS103_Informatik_I
eratosthenes(10)
print(zahlen)
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
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
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))
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))
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)
def quersumme(numb):
quer=0
43
Prüfungsvorbereitung MOS103_Informatik_I
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(_)
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