Abschnitt V
Dr.-Ing. Peter Ijewski 1/56
Kontrollfragen
17:13 Informationsverarbeitung Abschnitt V
Aufgaben des letzten Praxisteils
2/56
Vom Algorithmus zum Programm
Software Engineering
Programmiersprachen
Praxisteil
3/56
17:13 4/56 Informationsverarbeitung Abschnitt V
• Was ist Boolesche Algebra?
• Warum ist die Boolesche Algebra so wichtig für die Informatik?
• Welche „elementare Gleichungen“ kennen sie?
• Welches sind die sechs Eigenschaften eines Algorithmus?
• Was ist ein Pseudocode?
• Welche Aufgabe hat ein Pseudocode?
• Welche Alternative gibt es zum Pseudocode?
5/56
10:13 6/56 Informationsverarbeitung Abschnitt V
• Drücken Sie die „Ampelaufgabe“ in Form eines Booleschen Terms aus.
p= (¬r˄¬e˄ g)
˅ (¬r˄ e˄¬g)
˅ ( r˄¬e˄¬g)
˅ ( r˄ e˄¬g)
¬p= (¬r˄¬e˄¬g)
˅ (¬r˄ e˄ g)
˅ ( r˄¬e˄ g)
˅ ( r˄ e˄ g)
11:39 7/56 Informationsverarbeitung Abschnitt V
p = ( r*~e* g)
+ (~r* e*~g)
+ ( r*~e*~g)
+ ( r* e*~g)
~p= (~r*~e*~g)
+ (~r* e* g)
+ ( r*~e* g)
+ ( r* e* g)
Ausmultipliziert: ~r~eg+~re~g+r~e~g+re~g
Sortierung => ~eg~r+e~g~r+~e~gr+e~gr
Axiom 9': e~g~r + e~gr = e~g => ~eg~r+e~g+~e~gr
Axiom 9x': ~e~gr + e~g =~gr + e~g => ~eg~r+e~g+~gr
Ergebnis: p=~eg~r+e~g+~gr
Ausmultipliziert: ~r~e~g+~reg+r~eg+reg
Sortierung => ~e~g~r+eg~r+~egr+egr
Axiom 9': eg~r + egr = eg => ~e~g~r+eg+~egr
Axiom 9x': ~egr + eg = gr + eg => ~e~g~r+eg+gr
Ergebnis: ~p=~e~g~r+eg+gr
p=~e*g*~r+e~g+~g*r
~p=~e*~g*~r+e*g+g*r
~~p=~(~e*~g*~r+e*g+g*r) Ergebnis: p=~gr+e~g+~eg~r
p=(~e*g*~r+e~g+~g*r)*(~gr+e~g+~eg~r) Ergebnis: p=~gr+e~g+~eg~r
p=(¬g ˄ r)˅(e ˄ ¬g)˅(¬e ˄ g ˄ ¬r)
Siehe auch: http://www.elektroniker-bu.de/boolesche.htm
11:26 8/56 Informationsverarbeitung Abschnitt V
• Beschreiben Sie den Vorgang des Aufstehens am Sonntag (Sie haben vergessen den Wecker auszuschalten!)
function sonntag()
{
schlafe bis auf weiteres
{
falls der Wecker klingelt
{
falls nicht ausreichend Schlaf
{
Schlummertaste bedienen
}
anderenfalls
{
beende schlafen
}
}
falls selbstständiges Aufwachen
{
beende schlafen
}
}
Aufstehen
Waschen
Anziehen
Frühstücken
…
}
17:17 9/56 Informationsverarbeitung Abschnitt V
• Beschreiben Sie die Aufgabe „Solange würfeln bis eine sechs fällt“ in Pseudocode.
function würfeln()
{
wiederhole bis eine 6 fällt
{
würfle eine Zahl
}
}
function würfeln()
{
wiederhole
{
würfle eine Zahl
falls (Zahl==6)
{
beende Schleife
}
}
}
10/56
17:13 11/56 Informationsverarbeitung Abschnitt V
Begriffsdefinition
Algorithmus
Programm (Software)
• Grundlage jeglicher maschineller Informationsverarbeitung
• Beispiele aus dem Alltag: • Kochrezepte, Bedienungsanleitungen, Aufbauvorschriften • Mathematische Berechnungsverfahren
• (endliche) Folge von (eindeutigen) Anweisungen an einen Rechner => Handlungsvorschrift
17:13 12/56 Informationsverarbeitung Abschnitt V
Vorgehensweise
Problem
Algorithmus
Programm
Entwicklung eines geeigneten Algorithmus für die Problemlösung
Notation in der gewählten Programmiersprache
„handwerkliche“ Leistung
„künstlerische“ intellektuelle Leistung
17:13 13/56 Informationsverarbeitung Abschnitt V
Begriffsdefinition
Programmieren
Unter „Programmieren“ versteht man • das Notieren • eines zuvor erarbeiteten Algorithmus • in einer für den gewählten Rechner • lesbaren und ausführbaren Form.
11:45 14/56 Informationsverarbeitung Abschnitt V
Beispiel
Problemstellung
Berechne zu einer gegebenen Anfangs- und Endezeit einer Fernsehsendung ihre Dauer in Minuten. Voraussetzung: keine Sendung dauert länger als 24 Stunden.
17:13 15/56 Informationsverarbeitung Abschnitt V
Beispiel
Modellbildung
Eingangs-Information
Daten
Ausgangs-Information
Daten Maschinelle Datenverarbeitung
Repräsentation Interpretation
17:13 16/56 Informationsverarbeitung Abschnitt V
Beispiel
Modellbildung
• Abstraktion, geeigneten Ausschnitt der realen Welt bilden
• Erstellen des rechnerinternen Modells der realen Welt
• Fragestellungen - Was ist wie zu verarbeiten?
EVA - Prinzip
Eingabe: Anfangszeit (z. B.: 20:15), Endezeit (z. B.: 21:35)
Ausgabe: Dauer der Sendung (z. B.: 80 min)
Verarbeitung: Umwandung der Eingabedaten in Ausgabedaten
17:13 17/56 Informationsverarbeitung Abschnitt V
Beispiel
Pseudocode function SendungsDauer
{
input hA, mA, hE, mE falls (Sendung geht nicht über Mitternacht)
{
Dauer der Sendung = (hE * 60 + mE) – (hA * 60 + mA);
}
anderenfalls
{
Dauer der Sendung = ((hE + 24) * 60 + mE) – (hA * 60 + mA);
}
output Dauer der Sendung
}
17:13 18/56 Informationsverarbeitung Abschnitt V
Alternative Darstellungsformen
Ablaufdiagramm Quelle: Bundesministerium der Finanzen
17:13 19/56 Informationsverarbeitung Abschnitt V
Alternative Darstellungsformen
Nassi-Shneidermann-Diagramm Quelle: www.mathematik.net
17:13 20/56 Informationsverarbeitung Abschnitt V
Exaktheit. Die Funktion f kann präzise auf formale Weise beschrieben werden.
Finitheit. Die Beschreibung von f ist endlich lang.
Eigenschaften
Vollständigkeit. Die Beschreibung von f umfasst alle vorkommenden Fälle.
Effektivität. Die Einzelschritte sind elementar und real ausführbar.
Terminierung. Die Funktion f hält nach endlich vielen Schritten an und liefert ein Resultat.
Determinismus. Die Funktion f liefert bei gleichen Eingabewerten stets das gleiche Ergebnis, wobei die Folge der Einzelschritte für jeden Eingabewert genau festgelegt ist.
17:13 21/56 Informationsverarbeitung Abschnitt V
Beispiel
Pseudocode function SendungsDauer
{
input hA, mA, hE, mE Anfang_min = hA * 60 + mA; Ende_min = hE * 60 + mE; falls (Ende_min < Anfang_min)
{
Ende_min = Ende_min + 24 *60;
}
Dauer der Sendung = Ende_min - Anfang_min;
output Dauer der Sendung
}
17:13 22/56 Informationsverarbeitung Abschnitt V
Beispiel
Programm (C#) using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// Variablendeklaration
int h_anfang=0;
int min_anfang=0;
int h_ende=0;
int min_ende=0;
int Anfang_min=0;
int Ende_min=0;
int Dauer=0;
// Hole Eingabewerte
Console.WriteLine("Anfangszeit [h]");
h_anfang= Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Anfangszeit [min]");
min_anfang=Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Endezeit [h]");
h_ende=Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Endezeit [min]");
min_ende=Convert.ToInt32(Console.ReadLine());
// Rechne Zeitangaben in Minuten um
Anfang_min = h_anfang * 60 + min_anfang;
Ende_min = h_ende * 60 + min_ende;
if (Ende_min < Anfang_min) Ende_min = Ende_min + 24 *60;
Dauer = Ende_min - Anfang_min;
// Ausgabe auf der Konsole
Console.WriteLine("Dauer: "+Dauer);
Console.ReadLine();
}
}
}
23/56
17:13 24/56 Informationsverarbeitung Abschnitt V
Begriffsdefinition
„Zielorientierte Bereitstellung und systematische Verwendung von • Prinzipien, • Methoden • und Werkzeugen für die • arbeitsteilige, • ingenieurmäßige Entwicklung und Anwendung von umfangreichen Softwaresystemen.“ Quelle: Helmut Balzert: Lehrbuch der Software-Technik. Bd.1. Software-Entwicklung
17:13 25/56 Informationsverarbeitung Abschnitt V
Kernprozesse
1. Planung • Anforderungserhebung • Lastenheft (Anforderungsdefinition) • Pflichtenheft (Mit technischen Ansätzen verfeinertes Lastenheft) • Aufwandsschätzung • Vorgehensmodell
2. Analyse • Auswertung • Mock-up • Prozessanalyse / Prozessmodell • Systemanalyse • Strukturierte Analyse (SA) • Objektorientierte Analyse (OOA)
17:13 26/56 Informationsverarbeitung Abschnitt V
Kernprozesse
3. Entwurf • Softwarearchitektur • Strukturiertes Design • Objektorientiertes Design
• Fundamental Modeling Concepts
4. Programmierung • Normierte Programmierung
• Strukturierte Programmierung • Objektorientierte Programmierung (OOP)
• Funktionale Programmierung
17:13 27/56 Informationsverarbeitung Abschnitt V
Kernprozesse
5. Validierung und Verifikation • Modeless (Low-Level-Test) • Integrationstests (Low-Level-Test) • Systemtests (High-Level-Test) • Akzeptanztests (High-Level-Test)
17:13 28/56 Informationsverarbeitung Abschnitt V
Unterstützungsprozesse
6. Anforderungsmanagement 7. Projektmanagement 8. Qualitätsmanagement 9. Konfigurationsmanagement 10. Softwareeinführung 11. Dokumentation
• Die genannten Teilschritte werden nicht bei jedem Projekt komplett durchlaufen.
• Vielmehr werden die erforderlichen Prozesse spezifisch für die jeweilige Anforderung gewählt.
• Dies ist schon aus Sicht der Kosten- und Verwaltungsreduzierung dringend erforderlich.
17:13 29/56 Informationsverarbeitung Abschnitt V
Gründe
Eine Studie der Standish Group (1994) zeigte auf, dass
• nur 16% aller Softwareprojekte erfolgreich (hinsichtlich Zeit-, Budget und Funktionsvorgaben) abgeschlossen werden.
• Rund 53% der Softwareprojekte werden mit erheblichen Defiziten zu Ende gebracht.
• und 31% der Projekte scheitern gänzlich!
17:13 30/56 Informationsverarbeitung Abschnitt V
Teufelsquadrat für IT-Projekte nach Sneed
Qualität
Kosten
Funktionalität
Zeit
Konzentration auf ein Ziel erzwingt bei gleichen Rahmenbedingungen die Vernachlässigung mindes-tens eines anderen Ziels. (Verbesserung im Bild bedeutet ziehen des Schwerpunkts in diese Richtung.)
generelle Verbesserung nur durch Verbesserung der Rahmenbedingungen (z.B. der Prozesse).
Quelle: Stephan Kleuker, Grundkurs Software Engineering mit UML
17:13 31/56 Informationsverarbeitung Abschnitt V
Prinzipien bei der Entwicklung von Softwaresystemen
Abstraktion Hervorhebung des Wesentlichen, absehen von speziellen, untergeordneten Details, erkennen gleicher Merkmale
Hierarchisierung Anordnung der Elemente in einer Rangordnung. Elemente gleicher Rangordnung stehen auf derselben Stufe und bilden eine Schicht oder Ebene. Grundsatz: Innerhalb der Hierarchie dürfen keine zirkulären Beziehungen auftreten
Modularisierung "Modularisierung" ist ein allgemeines Prinzip aus den Ingenieur-wissenschaften und dient insbesondere der Erzeugung überschaubarer Systeme, deren Komponenten unter Umständen auch in anderen Systemen wiederverwendet werden können. Auf die Softwareentwicklung angewandt fordert dieses Prinzip die Aufteilung des Systems in überschaubare Teile, mit klar definierten Schnittstellen. Dabei sollen einzelne Module ausgetauscht oder geändert werden können, ohne dass Veränderungen im übrigen System erforderlich sind.
Lokalität Alle wichtigen Informationen, die zu derselben Situation gehören, sind an einem Platz vorhanden. Optimale Lokalität liegt vor, wenn die jeweils benötigten Informationen auf einer Seite stehen. Lokalität ist damit auch ein Strukturierungsprinzip.
integrierte Dokumentation
Ein Software-System besteht aus "Programmcode und Dokumentation" und ist letztlich nur so gut wie diese. Die Dokumentation muss integraler Bestandteil der Softwareentwicklung sein.
Quelle: www.spolwig.de/is/softwareprojekte/prinzipien.htm
32/56
17:13 33/56 Informationsverarbeitung Abschnitt V
Programmiersprachen
Auf einem Rechner wird ein Betriebssystem (Windows, Linux, Unix, etc.) installiert, um dem Anwender bei der Lösung seiner Aufgaben zu unterstützen.
Aufbauend auf der Betriebssystemschnittstelle müssen dazu Anwendungsprogramme bereit gestellt werden.
Die Erstellung derartiger Anwendungsprogramme (wie auch des Betriebssystems und anderer Softwarekomponenten ) erfolgt mittels Programmiersprachen.
Unter einer Programmiersprache versteht man eine formale Sprache, mit der eine auf einer Hardware ablauffähige Software entwickelt werden kann.
Beispiele: Java, C++, C#, Pascal, Cobol, Visual Basic, PHP, u.v.m.
17:13 34/56 Informationsverarbeitung Abschnitt V
Aufbau von Programmiersprachen
Eine Programmiersprache ist eine formale Sprache zur Formulierung von: • Datenstrukturen • und Algorithmen, d. h. von Rechenvorschriften, die von einem Computer ausgeführt werden können.
Sie setzen sich aus Anweisungen nach einem vorgegebenen Muster zusammen, der sogenannten Syntax.
17:13 35/56 Informationsverarbeitung Abschnitt V
Aufbau von Programmiersprachen
Die ersten Programmiersprachen orientierten sich sehr an den Eigenschaften der jeweiligen Rechner (Maschinensprachen).
Heute verwendet man meistens problemorientierte Sprachen, sogenannte Hochsprachen.
Diese erlauben grundsätzlich eine abstraktere und (für den Menschen) besser verständliche Ausdrucksweise.
In diesen Hochsprachen geschriebene Programme werden automatisiert in Maschinensprache übersetzt.
17:13 36/56 Informationsverarbeitung Abschnitt V
Entwicklung der Programmiersprachen
Quelle: goessner.net
17:13 37/56 Informationsverarbeitung Abschnitt V
Klassen von Programmiersprachen
• Maschinensprache, Assemblersprachen oder C (C++, C#) erlauben eine hardwarenahe Programmierung.
• CNC-Programmiersprachen (z. B. SPS, Sinumerik Operate) dienen der Erzeugung von Steuerungsinformationen für Werkzeugmaschinen.
• Datenbanksprachen (z. B. SQL) sind für den Einsatz in und die Abfrage von Datenbanken gedacht.
17:13 38/56 Informationsverarbeitung Abschnitt V
Klassen von Programmiersprachen
• Sprachen mit visuellen Programmierumgebungen (Visual Studio, etc.) erleichtern oder ermöglichen gar erst die graphische Gestaltung von Benutzeroberflächen.
• Skriptsprachen (cmd.exe, VBScript, sh, Perl, etc.) dienen zur einfachen Steuerung von Rechnern, wie bei der Stapelverarbeitung.
• Esoterische Programmiersprachen sind experimentelle Sprachen mit teilweise interessanten Konzepten.
Quelle: Wikipedia
• oder auch im WWW serverseitig (PHP, etc.) und clientseitig (JavaScript, etc.) zur Erstellung dynamischer Webseiten.
17:13 39/56 Informationsverarbeitung Abschnitt V
Übersetzungsprozess
In Hochsprachen geschriebene Programme werden automatisiert in Maschinensprache übersetzt.
• Kompilierende Programmiersprachen (Fortran, C, Pascal, etc.) Der Programmtext wird in Maschinensprache übersetzt und kann dann ausgeführt werden.
• Halbkompilierende Programmiersprachen (Java, C#, etc.) Der Quelltext wird in einen zunächst prozessorunabhängigen Zwischencode übersetzt und innerhalb einer Laufzeitumgebung (JVM, etc.) interpretierend ausgeführt.
• Interpretierende Programmiersprachen (JavaScript, Python, VBScript, etc.) Der Programmtext wird von einem Programm, dem sog. Interpreter schrittweise übersetzt und ausgeführt.
17:13 40/56 Informationsverarbeitung Abschnitt V
Übersetzungsprozess, vereinfachte Darstellung
Quelle: www.s-line.de
17:13 41/56 Informationsverarbeitung Abschnitt V
Übersetzungsprozess
• Der Quelltext (source code) als Anweisungsfolge wird in eine Datei geschrieben.
• Ein Compiler oder Interpreter übersetzt den Text in ausführbaren Maschinencode (Objekt-, Binärcode).
• Ein Binder (Linker) fügt ggfs. weitere Programmbibliotheken hinzu und rechnet relative in absolute Adressen um.
• Ein Lader (loader) als Dienst der jeweiligen Laufzeitumgebung (z.B. Betriebssystem) lädt das Programm in den Hauptspeicher und führt es aus.
Quelle: goessner.net
17:13 42/56 Informationsverarbeitung Abschnitt V
Vielfältige Programmiersprachen
www.99-bottles-of-beer.net one program in 1500 variations
99 bottles of beer on the wall, 99 bottles of beer. Take one down and pass it around, 98 bottles of beer on the wall. 98 bottles of beer on the wall, 98 bottles of beer. Take one down and pass it around, 97 bottles of beer on the wall. . . . 1 bottle of beer on the wall, 1 bottle of beer. Take one down and pass it around, no more bottles of beer on the wall. No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall.
17:13 43/56 Informationsverarbeitung Abschnitt V
Elemente einer Programmiersprache
Quelle: www.s-line.de
Variablen Zuweisen, Auslesen und Ändern von Speicherinhalten
Mathematische Operationen zumindest die vier Grundrechenarten
Verzweigungen
Abhängig von einer Bedingung wird ein anderer Programmfluss ausgewählt
Schleifen Wiederholen von Programmsequenzen
Blockbildung Zusammenfassung mehrerer Befehle
nicht mathematische Elemente
z. B. Text, Bilder, Video, Sound, etc.
Kommentare Kommentare beeinflussen den Programmablauf nicht. Sie dokumentieren den Quellcode.
17:13 44/56 Informationsverarbeitung Abschnitt V
Variablen
Im allgemeinsten Sinne ist eine Variable ein Behälter für Rechen-größen , die im Verlauf eines (Rechen-)prozesses auftreten.
Jede Variable ist gekennzeichnet durch:
• einen Namen • einen Datentyp
• eine Größe • den Inhalt
Die Wahl von Variablennamen bleibt im Allgemeinen völlig dem Programmierer überlassen.
Aber: Zur Vereinfachung der Nachvollziehbarkeit empfiehlt es sich dringend, möglichst selbsterklärende Variablennamen zu verwenden.
Oft verwendet man die sog. Ungarische Notation.
{Datentyp} {Bezeichner} z. B.: nStunde, cBezeichnung
17:13 45/56 Informationsverarbeitung Abschnitt V
Variablentypen
Präfix Datentyp Beispiel
n Integer nSize
b Boolean bBusy
sz null-terminierter String szLastName
p Zeiger pMemory
a Array aCounter
ch char chName
dw Double Word, 32 Bit dwNumber
w Word, 16 Bit wNumber
17:14 46/56 Informationsverarbeitung Abschnitt V
Initialisierung von Variablen
Variablen müssen vor Verwendung initialisiert werden.
// Variablendeklaration
int h_anfang=0;
int min_anfang=0;
int h_ende=0;
int min_ende=0;
int Anfang_min=0;
int Ende_min=0;
int Dauer=0;
17:14 47/56 Informationsverarbeitung Abschnitt V
Scope von Variablen
Quelle: wikipedia
17:14 48/56 Informationsverarbeitung Abschnitt V
Mathematische Operationen
In jeder Programmiersprache sind mindestens die vier Grundrechenarten verfügbar.
nWerta = nWertb+1;
nWerta = nWertb-1;
nWerta = nWertb*2;
nWerta = nWertb/3;
nWerta++;
nWerta--;
17:14 49/56 Informationsverarbeitung Abschnitt V
Verzweigungen
Abhängig von einer Bedingung wird durch Verzweigung ein anderer Programmfluss ausgewählt.
if (Ende_min < Anfang_min) Ende_min = Ende_min + 24 *60;
if (Ende_min < Anfang_min)
{
Ende_min = Ende_min + 24 *60;
}
17:14 50/56 Informationsverarbeitung Abschnitt V
Wiederholungen
Wiederholen von Programmsequenzen werden durch verschiedene Schleifenkonstrukte erreicht.
Dauer=0;
for (i=0; i<6; i++)
{
Dauer++;
//Ausgabe auf der Konsole
Console.WriteLine("Dauer:
"+Dauer);
}
Dauer=0;
i=0;
while (i<6)
{
i++;
Dauer++;
//Ausgabe auf der Konsole
Console.WriteLine("Dauer:
"+Dauer);
}
17:15 51/56 Informationsverarbeitung Abschnitt V
Blockbildung
Wiederholen von Programmsequenzen werden durch verschiedene Schleifenkonstrukte erreicht.
Dauer=0;
for (i=0; i<6; i++)
{
Dauer++;
//Ausgabe auf der Konsole
Console.WriteLine("Dauer:
"+Dauer);
}
if (Ende_min < Anfang_min)
{
Ende_min = Ende_min + 24 *60;
}
17:15 52/56 Informationsverarbeitung Abschnitt V
Bearbeitung nicht mathematischer Elemente
Hierzu gehören die Bearbeitung von Texten, Bildern, etc.
h_anfang= Convert.ToInt32(Console.ReadLine());
nLength = chName.Length;
private void button1_Paint(object sender, PaintEventArgs e) {
Bitmap bmp = new Bitmap(255, 255);
for (int i = 0; i < 255; i++)
for (int j = 0; j < 255; j++)
bmp.SetPixel(j, i, Color.FromArgb(i, 0, j));
e.Graphics.DrawImage(bmp, 0, 0);
}
17:15 53/56 Informationsverarbeitung Abschnitt V
Kommentare
Kommentare beeinflussen den Programmablauf nicht. Sie dokumentieren den Quellcode. // Hole Eingabewerte
Console.WriteLine("Anfangszeit [h]");
h_anfang= Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Anfangszeit [min]");
min_anfang=Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Endezeit [h]");
h_ende=Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Endezeit [min]");
min_ende=Convert.ToInt32(Console.ReadLine());
// Rechne Zeitangaben in Minuten um
Anfang_min = h_anfang * 60 + min_anfang;
Ende_min = h_ende * 60 + min_ende;
if (Ende_min < Anfang_min) Ende_min = Ende_min + 24 *60;
Dauer = Ende_min - Anfang_min;
// Ausgabe auf der Konsole
Console.WriteLine("Dauer: "+Dauer);
54/56
17:15 55/56 Informationsverarbeitung Abschnitt V
Aufgabe • Starten von Visual Studio (C#) • Erstellen des ersten Programms „Hello World“ • Programm „SendungsDauer“ • Programm „99 bottles of beer”
17:15 56/56 Informationsverarbeitung Abschnitt V
Danke für heute!
Top Related