ThInf-HOME

  1. Einführung

  2. Welche Daten werden benötigt?

  3. Die Datenstruktur Kassen/ Konten/ Accounts

  4. Die Datenstruktur Phase

  5. Übungsaufgaben


I-PROGRAMMIEREN1 WS 0203 - Vorlesung mit Übung
VL10: Projekt EARTHSIMULATOR1 - Schrittweise Umsetzung


AUTHOR: Gerd Döben-Henisch
DATE OF FIRST GENERATION: Nov-26, 2002
DATE OF LAST CHANGE: Dec-02, 2002
EMAIL: Gerd Döben-Henisch



1. Einführung

Aus der letzten Vorlesungen liegt nun ein Lastenheft und eine vereinfachte Systemanalyse zum EARTHSIMULATOR1 vor. Daraus kann man entnehmen, dass das Programm folgenden grundätzlichen Aufbau hat:


/************************************
 *
 * esim1.c
 *
 * author: gdh
 * first: dec-02,02
 * last: -
 * idea: Demoprogramm zur Umsetzung der Anforderungen an
 *       EARTHSIMULATOR1
 *
 * compilation: gcc -o esim1 esim1.c
 * usage: esim1
 *
 **************************************************/

int main(void){


  input_data();          /* Eingabe von Daten für Simulation */

while( BEDINGUNG ){

  compute_quantities(); /* Berechne die Veränderungen der Quantitäten der einzelnen Groessen */

  compute_money();       /* Berechne die Geldzu- und -abfluesse der verschiedenen Kassen */

  show_states();         /* Anzeige der Werte nach neuer Berechnung */

  BEDINGUNG = ask_for_interruption(); /* Unterbrechung aufgrund Voreinstellung oder aktueller Benutzeraktion */

 }

 return (1);
}

Nach der Eingabe notwendiger Daten für einen Simulationslauf tritt das Programm in eine Schleife ein, deren Inhalt darin besteht, die Zustandsveränderung der Erde vom Jahr t zum Nachfolgejahr t+1 zu berechnen, anzuzeigen und gegebenfalls 'Werte zu modifizieren. Die Berechnung kann man aufteilen in zwei Teilrechnungen: (a) Berechnung der Veränderungen in der Population (Zunahmen, Abnahmen); (b) Berechnungen der Geldflüsse zwischen den Grössen auf der Basis der neuen Mengenverhältnisse. Nachdem alle Berechnungen vorgenommen wurden, sollen (c) die neuen Werte auf dem Bildschirm angezeigt werden. Der Benutzer soll dann die Möglichkeit erhalten, (d) einzugreifen: die Simulation ganz stoppen oder nur einzelne Parameter justieren.

Im weiteren Verlauf soll dieses Grundschema nun Schritt für Schritt weiter ausgefüllt werden.

START


2. Welche Daten werden benötigt?


Das Programm beginnt mit der Abfrage von Daten vom Benutzer. Es stellt sich die Frage, welche Daten werden benötigt und in welchem Format sollen die Daten abgelegt werden?

Für die Beantwortung dieser Frage gibt es keine leichte Antwort, da die Antwort stark von Annahmen abhängig ist, welche Eigenschaften man dem Gegenstandsbereich zusprechen will. Die folgende Rekonstruktion ist von daher wieder nur eine Möglichkeit unter mehreren. Es wird angenommen, dass sich der Gegenstandsbereich anhand von Eigenschaften strukturieren lässt, die die sich als begrifflicher Baum ('conceptual graph') auffassen lassen (siehe Bild).



onto1
Strukturierung der Welt (earth) anhand von Eigenschaften



In dieser Rekonstruktion wird also angenommen, dass die Erde ('earth') aus Ländern ('country') besteht, ein Land wiederum setzt sich zusammen aus einer Population ('population') sowie aus diversen Kassen bzw. Konten ('accounts'). Für eine Population wird ferner angenommen, dass sie in Phasen ('phase') zerfällt. Diese Annahmen implizieren eine bestimmte Struktur in der Welt; man nennt dies auch häufig eine Ontologie ('ontology').

Wie man leicht feststellen kann, ist diese Grundstruktur für unsere Simulation noch zu abstrakt. Sie enthält viele Eigenschaften noch nicht, die für die Simulation benötigt werden. Also muss man versuchen, weitere Strukturen zu finden, solange, bis alle Eigenschaften, die für die Simulation benötigt werden, in der Ontologie repräsentiert sind.

START


3. Die Datenstruktur Kassen/ Konten/ Accounts


Als erstes soll überlegt werden, wie man die Eigenschaft Kassen bzw. Konten ('accounts') weiter analysieren kann. Ein Vorschlag für eine analyse wäre der folgender:



onto2
Strukturierung der Kassen anhand von Eigenschaften



Es wird also angenommen, dass ein spezielles Konto (Kasse) folgende Elemente enthält:

Übernimmt man diese Analyse, dann muss man sich fragen, wie man diese Eigenschaften mit den Mitteln der Sprache C kodieren kann. Eine naheliegende Möglichkeit ist die Übersetzung dieser Eigenschaften in eine Struktur, etwa:


#define CURRENCY_STRING_LENGTH 10

struct ACCOUNTS {

  float in;
  float out;
  float sum;
  float unit;
  char currency[CURRENCY_STRING_LENGTH];
};


Beispielhaft sei gezeigt, wie man die neue Datenstruktur ACCOUNT im Rahmen eines C-Programms nutzen kann. In eine Headerdatei esim1.h hinterlegt man die Definition der Struktur und im Hauptprogramm esim1.c definiert dann mittels des neuen Typs ACCOUNT die Variablen RK, AK, KK und AG. Bei der Definition kann man diese Variablen auf einen bestimmten Startwert hin initialisieren, wie im Beispiel demonstriert:


  /************************************
 *
 * esim1.h
 *
 * author: gdh
 * first: dec-02,02
 * last: -
 * idea: Headerdatei zum Hauptprogramm esim1.c
 *
 **************************************************/

#define CURRENCY_STRING_LENGTH 10

struct ACCOUNT {

  float in;
  float out;
  float sum;
  float unit;
  char currency[CURRENCY_STRING_LENGTH];
};



/************************************
 *
 * esim1.c
 *
 * author: gdh
 * first: dec-02,02
 * last: -
 * idea: Demoprogramm zur Umsetzung der Anforderungen an
 *       EARTHSIMULATOR1
 *
 * compilation: gcc -o esim1 esim1.c
 * usage: esim1
 *
 **************************************************/

#include <stdio.h>
#include "esim1.h"

int main(void){

  /* EINRICHTEN VON KONTEN MIT DEFINIERTEM ANFANGSWERT (INITIALISIERUNG) */

  struct ACCOUNT RK ={0.0, 0.0, 0.0, 1000.0, "Euro"};
  struct ACCOUNT AK ={0.0, 0.0, 0.0, 1000.0, "Euro"};
  struct ACCOUNT KK ={0.0, 0.0, 0.0, 1000.0, "Euro"};
  struct ACCOUNT AG ={0.0, 0.0, 0.0, 1000.0, "Euro"};

  /* KONTROLLAUSDRUCK (Beispiel RK und AK) */

  printf("INHALT VON RK: \n");
  printf("IN: %.2f \n",RK.in);
  printf("OUT: %.2f \n",RK.out);
  printf("SUM: %.2f \n",RK.sum);
  printf("UNIT: %.0f \n",RK.unit);
  printf("CURRENCY: %s \n",RK.currency);

  printf("INHALT VON AK: \n");
  printf("IN: %.2f \n",AK.in);
  printf("OUT: %.2f \n",AK.out);
  printf("SUM: %.2f \n",AK.sum);
  printf("UNIT: %.0f \n",AK.unit);
  printf("CURRENCY: %s \n",AK.currency);

 return (1);
}


START

4. Die Datenstruktur Phase


Als nächstes soll überlegt werden, wie man die Eigenschaft Phase ('phase') weiter analysieren kann. Aufgrund der vorausgehenden Anforderungen legt sich folgendes Konzept nahe:



onto3
Strukturierung der Phase anhand von Eigenschaften



Erläuterungen:

Mit dieser Analyse kann man die Menge der Personen, die eine Phase bilden, nach unterschiedlichen Eigenschaften in Untergruppen aufteilen. Neben allgemeinen Eigenschaften (wie interval, number, percentage_men, percentage_women und birthrate), die die ganze Phase betreffen, kann man Untergruppen unterscheiden (wie z.B. self_employed, employed, unemployed, education, retired_persons1, retired_persons2 und sick_persons). Übernimmt man diese Analyse, dann kann man, analog wie im Fall der Eigenschaft Konto (ACCOUNT), wieder eine entsprechende Struktur definieren. Allerdings würden dann noch Angaben darüber fehlen, wieviel jedes Mitglied der Untergruppen in die unterschiedlichen Kassen zu zahlen bzw. zu bekommen hätte.

Eine Möglichkeit, dieses Problem zu lösen, bestände darin, dass man sich auf den Standpunkt stellt, dass alle die genannten Untergruppen letztlich eine gemeinsame Struktur besitzen, nämlich die Struktur Zahler-Zahlungsempfänger ('PAYER_PAYEE'). Damit wäre folgende Analyse möglich:



onto4
Zusätzliche Strukturierung der Phase durch Zuordnung der Untergruppen an eine weitere Struktur PAYER_PAYEE



Wie liesse sich solch eine Datenstruktur in der Sprache C realisieren? Ein Beispiel zeigt die folgende Datei esim2.h:



/************************************
 *
 * esim2.h
 *
 * author: gdh
 * first: dec-02,02
 * last: -
 * idea: Headerdatei zum Hauptprogramm esim2.c
 *
 **************************************************/

#define CURRENCY_STRING_LENGTH 10

struct ACCOUNT {

  float in;
  float out;
  float sum;
  float unit;
  char currency[CURRENCY_STRING_LENGTH];
};

struct PAYER_PAYEE {

  float percentage_of_number;
  float actual_yearly_income;
  float last_yearly_income;
  float former_yearly_income;
  float RK_payment;
  float RK_income;
  float AK_payment;
  float AK_income;
  float KK_payment;
  float KK_income;
  float XRA_payment;
  float XRA_income;
  float AG_payment;
  float AG_income;
};

struct PHASE {

  unsigned int interval[2];
  unsigned long int number;
  float percentage_men;
  float percentage_women;
  float birthrate;
  struct PAYER_PAYEE self_employed;
  struct PAYER_PAYEE employed;
  struct PAYER_PAYEE unemployed;
  struct PAYER_PAYEE education;
  struct PAYER_PAYEE retired_persons1;
  struct PAYER_PAYEE retired_persons2;
  struct PAYER_PAYEE sick_persons;
};

Man kann deutlich erkennen, wie die beiden Strukturen PAYER_PAYEE sowie PHASE miteinander verschränkt werden. Da die Struktur PHASE die Struktur PAYER_PAYEE voraussetzt, muss die Struktur PAYER_PAYEE zuerst definiert werden. Nachdem dies geschehen ist, kann man in der neuen Struktur PHASE Elemente vom Typ PAYER_PAYEE definieren. Dies sind genau die Untergruppen, von denen wir wissen, dass sie entweder in eine der Kassen/ Konten einzahlen oder wenigstens von einer der Kassen Geld bekommen. Man kann aber auch erkennen, dass in der Struktur PAYER_PAYEE noch vier Elemente hinzugenommen wurden, die nicht im Bild dargestellt sind:

Das folgende kleine Programm zeigt beispielhaft, wie man diese neuen Strukturen PHASE und PAYER_PAYEE verwenden kann.


/************************************
 *
 * esim2.c
 *
 * author: gdh
 * first: dec-02,02
 * last: -
 * idea: Demoprogramm zur Umsetzung der Anforderungen an
 *       EARTHSIMULATOR1
 *
 * compilation: gcc -o esim2 esim2.c
 * usage: esim2
 *
 **************************************************/

#include <stdio.h>
#include "esim2.h"

#define COUNTRY_PHASE_NUMBER 5

int main(void){

  /* EINRICHTEN VON KONTEN MIT DEFINIERTEM ANFANGSWERT (INITIALISIERUNG) */

  struct ACCOUNT RK ={0.0, 0.0, 0.0, 1000.0, "Euro"};
  struct ACCOUNT AK ={0.0, 0.0, 0.0, 1000.0, "Euro"};
  struct ACCOUNT KK ={0.0, 0.0, 0.0, 1000.0, "Euro"};
  struct ACCOUNT AG ={0.0, 0.0, 0.0, 1000.0, "Euro"};

  /* EINRICHTEN VON PHASEN  */

  struct PHASE germany[COUNTRY_PHASE_NUMBER];


  /* KONTROLLAUSDRUCK KONTEN (Beispiel RK und AK) */

  printf("INHALT VON RK: \n");
  printf("IN: %.2f \n",RK.in);
  printf("OUT: %.2f \n",RK.out);
  printf("SUM: %.2f \n",RK.sum);
  printf("UNIT: %.0f \n",RK.unit);
  printf("CURRENCY: %s \n",RK.currency);

  printf("INHALT VON AK: \n");
  printf("IN: %.2f \n",AK.in);
  printf("OUT: %.2f \n",AK.out);
  printf("SUM: %.2f \n",AK.sum);
  printf("UNIT: %.0f \n",AK.unit);
  printf("CURRENCY: %s \n",AK.currency);

  /* BEISPIEL FUER DIE EINGABE UND DAS AUSLESEN VON DATEN BEI DER STRUKTUR PHASE */



printf("EINGABE DES INTERVALLS ('a b') in Jahren : ");
  scanf("%d %d",&(germany[0].interval[0]), &(germany[0].interval[1]));

  printf("\nKONTROLLE DES INTERVALLS ('a b') in Jahren\n");
  printf("germany 0: Anfang = %d Ende = %d\n",germany[0].interval[0], germany[0].interval[1]);

printf("\nEINGABE DER ANZAHL DER PHASE (in Mio.) : ");
  scanf("%d",&(germany[0].number));
printf("\nKONTROLLE DER ANZAHL DER PHASE (in Mio.) : ");
  printf("germany 0: Anzahl = %d\n",germany[0].number);


printf("\nEINGABE DES PROZENTSAZES VON SELBSTAENDIGEN AN DER PHASE ('x.x') : ");
 scanf("%f",&(germany[0].self_employed.percentage_of_number));
printf("\nKONTROLLE DES PROZENTSAZES VON SELBSTAENDIGEN AN DER PHASE\n");
  printf("germany 0: Prozentsatz Selbstendige = %.2f\n",germany[0].self_employed.percentage_of_number);


 return (1);
}


START

5. Übungsaufgaben

  1. Bilden sie ein Team von max.3 Mitgliedern


  2. Erstellung Sie gemeinsam einen Text mit Namen und Matr.Nr. der AutorenInnen. Abgabe einer Kopie des Textes an den Dozenten vor Beginn der Vorlesung am Di (1 Woche nach Aufgabenstellung). Falls die Aufgabe ausführbaren Programmcode enthält wäre die zusätzliche Übergabe des Quelltextes auf Diskette oder per email wünschenswert. Im Falle von Programmcode muss im Programmtext auch nochmals Name und Matr.Nr. erscheinen.


  3. Präsentation der Lösung als Team vor der gesamten Gruppe. Präsentationszeit (abhängig von der Gesamtzahl der Teams) 3-5 Min. Mögliche Punkte: 1-3 im Normalfall. (Im Falle von mehr als 1 Autor ist die ausführliche Besprechung in der Übung Voraussetzung für die Vergabe der Punkte!)


  4. Versuchen Sie in dem Text Antworten auf folgende Aufgaben zu formulieren:


  5. Auf der Basis der Spezifikationen des EARTHSIMULATOR1 aus der Vorlesung VL9 sowie aufgrund der Analyse möglicher Datenstrukturen aus VL 10 erarbeiten Sie einen Vorschlag für die Eingabe der Daten für ein Land.



START