5.2. Programmierung history menue Letztmalig dran rumgefummelt: 06.05.19 19:49:33
Ein Programm ist die Umsetzung eines Algorithmus und der zugehörigen Datenbereiche in eine Programmiersprache. Während Algorithmen relativ allgemein beschrieben werden können, sind Programme wesentlich konkreter.
Nach DIN 44300 ist ein Programm eine „nach den Regeln der verwendeten Programmiersprache festgelegte syntaktische Einheit aus Anweisungen und Vereinbarungen, welche zur Lösung einer Aufgabe notwendige Elemente umfasst“. Eng mit dem Programm verknüpft sind Begriffe wie: Algorithmus, Daten, Datei, Variablen Datentypen, Resultate, Software.
Nicht unbedingt ist der Begriff des Programms an den Computer gebunden (wenngleich er heute meist damit im Zusammenhang zu sehen ist!!!), so gibt es Veranstaltungsprogramme, das Fernsehprogramm (wahrscheinlich das bekannteste), selbst der Fahrplan der Bundesbahn repräsentiert ein Programm eine Folge von Schritten (deren Ablauf) nach einer geplanten Reihenfolge.

0. Top-Down-Entwicklung am Beispiele
1. Programmentwicklung - Top-Down-Denken
2. Programmfehler
3. Compiler und/oder Interpreter
4. Anforderungen an ein Pogramm und an den Programmierer
5. Programm-Dokumentation
6. Maschinenprogrammierung
7. Echtzeitverhalten und Echtzeitsysteme
8. Programmierbeispiele
9. Verwandte Themen

die Informatikseiten

Programmierungs-Logo

begrenzt verwendbar - selbst aufpassen, ab welcher Stelle es Blödsinn wird ;-)

Wissen für Fortgeschrittene der Informatik

Informatik-Profi-Wissen

Quellen:

Stammbaum der Programmiersprachen


0. Top-Down-Entwicklung history menue scroll up

Die Top-Down-Entwicklung versteht sich als die Methode: "... von der Spitze des Problems herab zum absoluten Einzelschritt".
Top-Down Entwicklung (wörtlich übersetzt: TOP-DOWN - von der Spitz nach unten besser: vom Problem zum lauffähigen Programm)
1. Aufgabenstellung:
- wenn Ihnen eine Aufgabe nicht gestellt ist, dann versuchen Sie so exakt wie nur möglich zu formulieren, was Ihr zu erstellendes Programm zu leisten hat
- verschaffen Sie sich Klarheit darüber, ob Ihr Problem überhaupt in einen Algorithmus und damit auf dem Rechner formulierbar ist - beachten Sie Probleme mit schwer fassbaren Größen (evtl. Unendlichkeit zu verarbeitender Größen)
- beginnen Sie bereits hier mit dem notwendigen Fachstudium - was müssen Sie beherrschen, um die Aufgabe zu lösen?
Beispiel:
Ermitteln Sie in einem Programm die Fallzeit und die Fallgeschwindigkeit bei variabel vorzugebender Höhe!
2. Problemanalyse:
- Erstellen des notwendigen mathematischen oder sonstigen Algorithmus
- Festlegung der Ausgabegrößen (dies sind diejenigen, die laut Aufgabestellung "gesucht...", oder "zu ermitteln..."sind)
- Festlegung der Eingabegrößen (sind dann die Größen, die der mathematische Algorithmus benötigt und die nicht Ausgabegrößen sind)
- Entwicklung aller logischen zusammenhänge des Programms - beachten Sie hier besonders anzuwendende Maßeinheiten!
- Datendefinition nach Typen und Anzahl
- wie komme ich vom Gegebenen zum Gesuchten?
Beispiel:
Formeln:
v=s:t;
t=Wurzel(2 x h:g)
Eingabe:
hoehe:REAL;
Ausgabe:
endgeschwindigkeit:REAL in m/s und km/h
fallzeit:REAL in sec.
Konstante:
erdbeschleunigung:REAL=9.81 m x s-²
Problem:
was wird mit Eingaben hoehe<0?
3. Algorithmierung:
... ergibt eine eindeutige Vorschrift zur Lösung einer Aufgabe mit endlicher Schrittzahl und festgelegter Reihenfolge.

• geschieht entweder im TOP-DOWN oder BOTTOM-UP-Verfahren ((BOTTOM-UP: von unten nach oben) leider bei vielen Computerfreaks sehr verbreitet)
• Erstellung eines Struktogrammes oder Pseudocodes
• Erstellung eines Datenflußplanes
Beispiel:
>>vereinbarung aller benötigten daten<<
>>read hoehe<<
>>fallzeit:=sqrt(2*hoehe/erdbeschleunigung)<<
>>endgeschwindigkeit:=erdbeschleunigung*fallzeit<<
>>write fallzeit,endgeschwindigkeit<<
seien Sie sich bewußt, daß Sie bis zum Abschluß dieses Schrittes vollkommen frei von der Programmiersprache sind, diese Entscheidung müssen Sie erst hier treffen - können natürlich bei der späteren Umsetzung in eine andere Sprache bis hierher äquivalent bleiben!
4. Progammierung und Implemaentation:
PROGRAM fall (INPUT,OUTPUT);

USES
WINCRT;

CONST
erdbeschleunigung=9.81;

VAR
hoehe:REAL;
fallzeit:REAL;
endgeschwindigkeit:REAL;

{************************** Haupptprogramm ***************************}

BEGIN{begin mainroutine}
CLRSCR;
WRITELN('Dieses Programm berechnet Ihnen Fallzeit und');
WRITELN('Endgeschwindigkeit beim freien Fall von Körpern');
WRITELN('aus verschiedenen Höhen');
WRITELN;
WRTIELN('>ENTER<');
REPEAT
UNTIL KEYPRESSED;
WRITE('Bitte geben Sie jetzt die Höhe in Metern ein: ');
READLN(hoehe);
CLRSCR;
fallzeit:=SQRT(2*hoehe/erdbeschleunigung);
endgeschwindigkeit:=erdbeschleunigung*fallzeit;
WRITELN('Die Endgeschwindigkeit beträgt: ',endgeschwindigkeit,' m/s');
WRITELN('Die fallzeit beträgt: ',fallzeit,' s');
READLN;
END.{end of program}

{****** Copyrights by F. Rost - Arbeitsstand: 10.11.1995 *******}
5. Programmtest und Korrektur:
• testen Sie mit einfachen Größen (probieren Sie mit nachkon-trollierbaren Ergebnissen - also kleinen Zahlen)
• testen Sie mit großen Zahlen - rechnen Sie mit Taschenrechner nach
• testen Sie auf kritische Größen, z. B.: 0, 1, Grenzwerten des zugelassenen Bereiches
• bauen Sie nun Sicherheiten gegen Fehlbedienung ein
6. Dokumentierung:
• kommentieren Sie Ihre Programme gut
• legen Sie mehrere ausgetestete Kopien an
 

... Delphi - heute RAD-Studio

... Delphi - Beispiele

klassische BASIC-Programmierung - der Wissensspeicher

... der AVM - BASCOM-Compiler

PASCAL-Programmierung

... der Microsoft- VCBA-BASIC Interpreter

... das alte KC-85/X-BASIC

brandneu 2004 im Hause - JAVA

... fast nur bei uns: Just Anather Lanuage

die Befehlsdokumentation GW-BASIC - eine Ausarbeitung aus dem Jahre 1992 unter Mitarbeit von Schülern des Gymnasiums Flöha stellen wir hier vor (allerdings mit einer Größe von 2,059 MByte)

... das Programmiersystem für Anfänger - Robot Karol

Scratch

       
 
 
 


1. Programmentwicklung history menue scroll up

Hier läuft die Problemlösung, der Algorithmus, die Lösungsverfahren, Software-Engeneering und die Wahl der Programmiersprache miteinander konform.
die Befehlsdokumentation GW-BASIC - eine Ausarbeitung aus dem Jahre 1992 unter Mitarbeit von Schülern des Gymnasiums Flöha stellen wir hier vor (allerdings mit einer Größe von 2,059 MByte)
Der Editor ist eine Schreibfläche innerhalb des Programmsystems, die ähnlich wie ein Textverarbeitungssystem arbeitet (viele Funktionen sind sogar gleich). Erkennbar ist der Editor an seinen Menüsymbolen. Seine Aufgabe ist es, den Programmquelltext aufzunehmen, zu verändern und auch abzuspeichern.
der Quelltext ist das im Editor stehende fertige Programm, nachdem die Schritte der Programmentwicklung durchlaufen wurden. Der Quelltext ist unmittelbar an das Programmiersystem gebunden, er muss in eben der gewählten Programmiersprache geschrieben sein. Er enthält die syntaktischen Anweisungsfolgen der gewählten Programmiersprache.
Beachten muss man, dass jede Programmiersprache Vorteile, aber auch Nachteile hat.


2. Programmierfehler history menue scroll up
Streng unterschieden werden muss hier unabhängig von der Programmiersprache, in welcher Form das Programm aktuell betrachtet jeweils gerade vorliegt. Das Entwicklungszeitraster ist etwas ganz anderes als das Compiler- oder gar das Laufzeitraster. Interpreter nehmen hier eine Zwischenstellung ein.

Fehler verhindert man dadurch, dass man keine Fehler macht. Zu diesen Zweck sollte man zuallererst gute und vernünftige Werkzeuge benutzen. Dazu gehören eine dem Problem angemessene Sprache und gute, zuverlässige Compiler.

Als nächstes sollte man die Maxime „Erst überlegen, dann programmieren“ beherzigen. Das Programm, die Module, die Datenstrukturen sollen vorher geplant sein. Wenn das Design nicht stimmt, kann das Programm später sehr kompliziert werden. Je komplizierter ein Programm ist, um so  höher seine Fehleranfälligkeit. Früh begangene Fehler rächen sich später. Je später ein Fehler gefunden wird, um so mehr Kosten verursacht er.
Als dritter Punkt ist ein sauberer, klarer Programmierstil wichtig. Der Versuchung, durch undurchsichtige Tricks noch ein Quentchen Effizienz hervorzukitzeln, sollte unbedingt widerstanden werden. Erst nachdem ein Programm korrekt läuft, ist es angebracht, mit Werkzeugen wie Profilern die Stellen herauszufinden, wo sich eine Effizienzsteigerung auswirken würde, und diese Stellen punktuell zu optimieren. Zu einem guten Programmierstil gehört natürlich auch, das Programm für menschliche Leser verständlich und übersichtlich zu halten. Unabdingbar sind in diesem Zusammenhang eine gute Dokumentation, ein Zerlegen in überschaubare Teilaufgaben, die Vermeidung von globalen Variablen und Seiteneffekten.

Auch dem gewissenhaftesten Programmierer unterläuft trotz aller Vorsichtsmaßnahmen gelegentlich ein Fehler. Um solche Fehler zu finden und ggf. zu vermeiden, bietet der Compiler gewisse Möglichkeiten: Durch Schalter (switches) lassen sich Prüfroutinen in den Code einbinden, die Bereichsüberschreitungen, Stack-Überlauf und falsche Eingabewerte abfangen. Erst wenn auf diese Weise das Vertrauen in die Software gestärkt wurde, stellt man die Schalter so, dass die Prüfroutinen weggelassen werden. Aber auch ohne Hilfsmittel kann der Programmierer das interne Verhalten des Programms diagnostizieren. Durch WRITE-Befehle können Inhalte von Variablen, Parametern und Zwischenwerten ausgegeben werden. Zwischenbehauptungen, d.h. Annahmen über die Beziehung von Variablen untereinander, können getestet werden, wenn sie als Boolesche Ausdrücke formuliert vorliegen. Ist eine solche Zwischenbehauptung nicht erfüllt, so wird ein Fehler gemeldet. Als Testroutine könnte die folgende Prozedur dienen:

PROCEDURE assert (f_behauptung:BOOLEAN;f_nummer:INTEGER); 

BEGIN{begin of procedure assert}
  IF NOT f_behauptung
  THEN
  BEGIN{begin of then}
    WRITELN(‘Zwischenbehauptung Nr. ’,f_nummer,’ verletzt’);
    assert((x>0)AND(sum=x*(x+l) div 2),17);
  END;{end of then}
END;{end of procedure assert}

Wird während des Programmablaufes eine solche Zwischenbehauptung verletzt, so erfolgt eine entsprechende Fehlermeldung.
Alle diese Methoden sind Testmethoden. Sie sind einfach durchzuführen, führen schnell zum Ziel und sind auch bei beliebig komplexen Programmen anwendbar. Leider sind Testmethoden unzuverlässig, weil man nie alle möglichen Eingaben testen kann. Ein Zitat von E. DIJKSTRA bringt dies auf den Punkt: „Durch Testen kann man die Anwesenheit, nie aber die Abwesenheit von Fehlern zeigen.“
Dem wollen wir nun eine Methode entgegensetzen, mit der die Korrektheit von Programmen formal bewiesen werden kann. Die Methode ist nicht schwierig, aber dennoch aufwendiger als das Testen. Daher lohnt sich eine formale Verifikation nur bei Anwendungen, deren absolute Zuverlässigkeit gewährleistet sein muss.
In Analogie zur Mathematik kann man feststellen, dass sich das Testen von Programmen zur Verifikation von Programmen verhält wie das Ausprobieren von mathematischen Sätzen zu deren Beweis.

Programmfehler: Fehlerfrei größere Projekte zu programmieren, ist beinahe unmöglich. Man unterscheidet insgesamt drei Gruppen von Fehlern:
  • Compilerfehler: man hat gegen die Anforderungen des Quelltextes verstoßen, der Compiler meldet den Fehler mit einer Nummer und einer Stelle im Text. Leider ist das nur selten die Stelle, wo der Fehler gemacht wurde. Dagegen steht der Cursor immer an der Stelle, wo der Fehler sich auswirkt!
  • Laufzeitfehler: man hat gegen die Anforderungen des Laufes von Programmen verstoßen. Auch der Computer kennt keine Division durch Null. Er bricht bei einer solchen einfach die Arbeit ab um zu verhindern, dass das Programm falsch weiterarbeitet.
  • Logische Fehler: In unserem Programm steckt in diesem Falle ein Fehler, der nur sehr schwer bemerkt wird, denn das Programm arbeitet und bekommt bei Anwendung mathematischer Funktionen Ergebnisse. Bei Nachkontrolle aber stellt sich heraus, dass diese Ergebnisse falsch sind. Ursache sind Fehler in der Anordnung der Formeln. Wenn statt zu Multiplizieren eben addiert wird

3. Compiler und Interpreter history menue scroll up
Natürlich begeben wir uns hier ins Reich der heiligen Kühe (wieder mal). Natürlich einigen wir uns darauf, dass ein Compilersytem eine Mehrheit an Vorteilen bietet, dass aber ein interpretatives System eben auch seine guten Seiten hat - und, nun kommt's: Nutzen nicht auch Compilersyteme so etwas "Primitives" wie Breakpoints? Richtig ein interpretatives System, bis eine definierte Stelle erreicht wurde, oder diese nicht erreicht werden kann, da Fehler im Programm? Das übrigens Interpreter eine Reihe von Fragen offen lassen, liegt nicht an der Philosophie des Systems an sich, sondern daran, dass sie schlecht oder unbedacht bezüglich Worst-Case gemacht sind. Niemand hätte Bill Gates daran hindern können, einen Interpreter zu schreiben, in welchem auch die Variablen einschließlich ihrer Datentypen deklariert werden müssen.
Ist ein Übersetzerprogramm, der einen Programmtext in eine, dem Computer verständliche Sprache (Maschinensprache) übersetzt. Nach dem Lauf des Compilers liegt unser Programm genau zweimal im Hauptspeicher des Computers. Nämlich einmal als Quelltext, einmal als Maschinenprogramm. Das ist die Sprache, welche letztendlich als Befehl vom jeweiligen Prozessor verstanden und abgearbeitet werden kann. Ist die Hochsprache selbst frei für die jeweilige Plattform, so ist es der betreffende Compiler nicht mehr, denn er übersetzt direkt in die Zielsprache.
Das Gegenstück eines Compilers ist ein Interpreter. Hier werden jeweils Programmzeilen übersetzt und anschließend sofort ausgeführt. Das bringt insbesondere bei der Programmentwicklung Vorteile. Beide haben Vor- und Nachteile, wenn es allerdings um Geschwindigkeit geht, ist ein Compiler immer die effektivere Lösung.

4. Anforderungen an ein Programm und an den Programmierer history menue scroll up
Gut entwickelte Programme ...
  1.  ...lassen ihren Nutzer nie vor einem leeren Monitor sitzen, sondern informieren immer, was getan werden kann oder muss um weiterzukommen. Dabei ist die Menüführung eindeutig, überlegt sowie leicht überschaubar. Bei komplexeren Abläufen ist eventuell eine kontextbezogene Hilfe vorzusehen.
  2.  ...verfügen über eine logisch klare und minimal orientierte Datenvergabe.
  3.  ...fangen fehlerhafte Eingaben (Bereichsüberschreitungen, falsche Tasten, falsche Laufwerkszugriffe, Buchstaben statt Zahlen und umgekehrt usw.) mit entsprechenden Informationen für den Nutzer ab. Im Prinzip dürfen keine Laufzeitfehler auftreten.
  4. ...enthalten soviel Kommentare, wie Quelltext selbst!
  5.  ...sind gut strukturiert und damit leicht lesbar - die Funktion jeder Variablen ist aus dem Listing entnehmbar (gegebenenfalls werden mögliche Werte der Variablen im Text notiert).
  6.  ...führen mit knappen, aber präzise formulierten Aussagen über den Monitor (orientieren Sie sich dabei an professioneller Software).
  7.  ...enthalten in jedem Programmblock eine kurze Information, welche Funktion er ausführt.
  8.  ...greifen auf Dateien niemals zerstörend zu - Fehlbedienungen sind abzuweisen.
    9. ...verwenden Farbe sparsam und mit Funktion - besonders eignen sich ansonsten blauer Hintergrund mit weißem Text (Hervorhebungen mit gelb betonen!).
  9. ...nutzen keine unnötigen Spielereien (Blinken, Ton usw.), sondern konzentrieren sich auf das versprochene Leistungsangebot, welches knapp als Eingangsmenü geboten werden sollte.
  10. ...bringen Sprunganweisungen nur nach vorn zur Anwendung, ansonsten (rückwärts) nur um Schleifen zu schließen. Jedes Programm verfügt über nur eine END-Anweisung.
  11. ...wenden sich immer an den „naiven“ Nutzer und schränken diesen so wenig wie möglich ein - bieten statt dessen selbst einen großen Leistungsumfang.
  12. ...sind wartungsfreundlich und nach oben offen - also überschaubar!
  13. ...sind modular aufgebaut und verwenden möglichst viele Subroutinen (Unterprogramme), welche klein und universell verwendbar sind
  14. ...wechseln zwar Verzeichnisse, kehren aber nach Programmende selbständig in's Ausgangsverzeichnis zurück!
  15. ...erreichen in einer, dem Problem relevanten Abarbeitungszeit eine eindeutige und möglichst richtige Lösung!

Demgegenüber werden auch Sie nach kurzer Zeit feststellen, dass dies einfach und logisch klingt, jedoch gar nicht so einfach realisierbar ist!

Und nun folgen die Forderungen an Sie:

I. Sinn und Zweck des Programms darlegen.
II. Programm in logisch möglichst unabhängige Blöcke gliedern.
III. Schnittstellen zwischen den Stellen explizit angeben., Informationsfluss zwischen den Blöcken über die Schnittstellen abwickeln.
IV. Programmtext optisch gliedern.
V. nach Bedarf Kommentare einfügen.
VI. Variablen und Konstanten ihrer Bedeutung gemäß benennen.
VII. Vor jede Eingabe eine Anfrage des Rechners stellen, Antwortalternativen angeben.
VIII. Jeder Ausgabe einen erläuternden Text beigesellen.
IX. Einfach und direkt programmieren, keine Tricks; Klarheit und Übersichtlichkeit haben Vorrang vor Schnelligkeit im Ablauf.
X. Ergebnisse im Zusammenhang des gegebenen Problems interpretieren.

die bearbeiteten Biographien stellen wir hier mit 569 KByte vor ( - die gibt's wegen der Größe von 1,7 MByte als Word-Dokument auch noch mal als ZIP-Archiv)

5. Programm-Dokumentation history menue scroll up
Eines der wichtigsten Programm-Beschreibungsmöglichkeiten sind Ablaufpläne sowie Struktogramme. Sauberdurchgeführte Programmdokumentation sind weitere Grundlagen der Software-Entwicklung im Team. Denn hier werden Schnittstellen, gemeinsam benutzte Größen, Datentypen und Übergabeparameter definiert.
Pseudocode-Notation
Struktogramme
Beispiel für eine Programm-Dokumentation zum Post'schen Korrespondenzproblem hier

6. Maschinenprogrammierung history menue scroll up

 
 
 


7. Echtzeitverhalten und Echtzeitsysteme history menue scroll up

Das ist eine Extremforderung an Software, welche mit genau dafür zugeschnittener Hardware ein Maximum an Effizienz, ein Minimum an Redundanz und damit wiederum ein Minimum an Rechenzeit zu erreichen sucht. Es gilt hier, in extrem kurzer Zeit auf Ereignisse von außen angemessen zu reagieren (also auch nicht über zu reagieren). Echtzeitsysteme haben ihr zu hause in der Industrie, der Weltraumfahrt
 
 


8. Programmierbeispiele history menue scroll up

Zunehmend etappliert sich das Lazarus-Programmiersystem an den Schulen Deutschlands als kostenfreie Programmiersprache, welche auch allen Anforderungen gerecht wird und über hinreichende Mächtigkeit im Leistungsumfang verfügt. Besonders positiv ist seine Verwandtschaft zu Delphi.
Delphi-Beispiele JAVA-Script Delphi & Lazarus    

... Delphi - Beispiele

 

JAVA-Script

... das Textverarbeitungsprojekt

 

   
 


9. Verwandte Themen history menue scroll up

Im Begriff Wide-Aera Network läuft ja nun eigentlich technisch die gesamte Informatik zusammen - können und wollen wir gar nicht alles bedienen - aber einiges haben wir und stellen es als Denkanstoß auf diesen Links zur Verfügung. Schnell ist man natürlich im Innenleben der Netzwerke - nur für ganz harte Burschen geeignet ;-)
Bereich höhere Programmiersprachen

Worst-Case-Denken

ASide-Assembler

 
Bereich Datenübertragung

Datenübertragungsverfahren

OSI Referenz-Schichtenmodell

die RS232-Schnitttstelle

Tabelle des UNICODES

Kryptologie

Digitale Signale

Information, Nachricht und Signalbegriff

 

   
Bereich Netzwerke und Sicherheitstechnik

Secuirty-Syteme in Netzwerken

Server-Management

Local Area Network - kurz: LAN

Netzwerkdienste

Netzwerk-Management

OSI Referenz-Layer

Netzwer-Topologie

Terminalserver

 
Anfängerbereich Informatik

Computer für Anfänger

Computertechnik

Mikroprozessor und Peripherie

Netzwerke für Anfänger

Standardsoftware

Betriebssysteme

Software-Lifecycle

   
Bereich Mikroprozessortechnik und Einchipcontroller

der LC-80

POLYCOMPUTER

Z80-CPU

Mnemonic-Code-Notation

höhere Programmierwerkzeuge

... und so funktioniert ein Computer

 

die beliebte alphabetisch sortierte Schnell-Liste

die beliebte numerisch sortierte Schnell-Liste

Allgemeine FLAG-Wirkung

FLAG-Wirkung auf OP-Code-Gruppen

Alphabetisch sortierte Dokumentation

FLAG Teile I

FLAG Teile 2

Allgemeine Funktionssymbolik

Der LC-80 Simulator

Microcontroller

   
Bereich Programmierungstechnik

Programme

Programmiersprachen

Software-Engeneering

Datentypen - sind ja auch besond're Typen gewesen ;-)

Logo der Struktogramme

EVA-Prinzip & Objekt-, Attribut-, Operatiosnbeziehung

Modultechnik

Intel-Interrupt-Logo

 
Bereich Rechentechnik und Betriebssysteme

Computergeschichte

von-Neumann-Architektur

Logo der Parallelrechnersystemee

Betriebssysteme

   



zur Hauptseite
© Samuel-von-Pufendorf-Gymnasium Flöha © Frank Rost im Oktober 2007

... dieser Text wurde nach den Regeln irgendeiner Rechtschreibreform verfasst - ich hab' irgendwann einmal beschlossen, an diesem Zirkus (das haben wir schon den Salat - und von dem weiß ich!) nicht mehr teilzunehemn ;-)

„Dieses Land braucht eine Steuerreform, dieses Land braucht eine Rentenreform - wir schreiben Schiffahrt mit drei „f“!“

Diddi Hallervorden, dt. Komiker und Kabarettist

Diese Seite wurde ohne Zusatz irgendwelcher Konversationsstoffe erstellt ;-)