Einzelnen Beitrag anzeigen

Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#3

Re: Speichern und umwandeln von records und arrays

  Alt 11. Apr 2007, 16:30
Hi und erstmal herzlich Willkommen in der Delphi-Praxis

Als erstes möchte ich mal eine Sache loswerden: Dein Code ist scheußlich!
Klar, Du hast schon gesagt, dass Du kein großer Delphi-Programmierer bist und da Du mit Chromosomen zu tun hast, würde ich mal darauf tippen, dass Du auch kein Informatik-Student sein dürftest?
Jedenfalls beziehe ich mich nicht auf die Semantik oder Syntax (hab Deinen Code noch nicht näher gelesen), sondern allein auf die Optik. So hast Du hier sehr merkwürdig eingerückten Code gepostet, zudem scheint mir auch etwas viel Logik in dieser einen Methode zu stecken.
Hier solltest Du Dir dringen anschauen, was es für Mittel der Strukturierung gibt und wie man diese verwendet (Stichwort Procedure und Function).

Auch was das Einrücken angeht, so solltest Du dieses zu Strukturierung verwenden. Das macht den Code sehr viel einfacher lesbar und damit weniger Fehleranfällig. Vorallem werden aber auch Deine Korrektoren eine erhöhte Chance haben den Code einfach zu verstehen und das kann doch positive Auswirkungen auf die Note haben.
Exemplarisch könnten wir hier folgenden Abschnitt betrachten:
Delphi-Quellcode:
 begin
 randomize;
   //Anmerkung: k muss kleiner oder gleich maxN sein.
   Write ('Bitte geben sie die Anzahl der Populationen ein:');
        Readln (N);
        //Write('Bitte geben Sie die Groesse k der Teilpopulation an (max. ', maxN, '): ');
   //ReadLn(k);



     for s:=1 to N do begin




      for j:=1 to 10 do begin

      geno.chromosom1[j] := Random(2);


                geno.chromosom2[j] := geno.chromosom1[j];

      //Speichert, welche chromosomen noch nicht geändert wurden.
      besucht[j] := false;
           end;

                //Gibt die Anzahl der stattfindenden Vertauschungen an, sprich die Allelfrequenz. Hier 0,5-->5 Vertauschungen
            vertauschungen := 5; //später bei mehr oder weniger Vertauschungen :=random(10)+1
Vergleich den mal mit folgendem:
Delphi-Quellcode:
begin
  randomize;
  
  //Anmerkung: k muss kleiner oder gleich maxN sein.
  Write ('Bitte geben sie die Anzahl der Populationen ein:');
  Readln (populationCount);
  //Write('Bitte geben Sie die Groesse k der Teilpopulation an (max. ', maxN, '): ');
  //ReadLn(k);

  // Kommentar was die Schleife macht
  for i := 1 to populationCount do
  begin
    // Kommentar, was die Schleife macht
    for j := 1 to 10 do
    begin
      geno.chromosom1[j] := Random(2);
      geno.chromosom2[j] := geno.chromosom1[j];

      //Speichert, welche chromosomen noch nicht geändert wurden.
      besucht[j] := false;
    end; // for j := 1 to 10

    //Gibt die Anzahl der stattfindenden Vertauschungen an, sprich die Allelfrequenz. Hier 0,5-->5 Vertauschungen
    vertauschungen := 5; //später bei mehr oder weniger Vertauschungen :=random(10)+1
Ich hoffe Du siehst da ein paar (positive) Unterschiede. Im zweiten Fall wurden z.B. ein paar Variablen (ansatzweise) umbenannt. Findet jmd. etwas wie N, wird garantiert keiner wissen, was diese Variable speichert! Auch bei Zählvariablen solltest Du möglichst zu Buchstaben ab i greifen, für die äußerste Schleife überlicherweise i, für die nächste innere j usw.
Hierachie sollte immer durch einrückung (Code steht einen Tabulator weiter rechts) angezeigt werden. Hier siehst Du dann einfach, was z.B. den beiden Schleifen zugeordnet ist. Das was auf der gleichen Hierachiestufe steht, sollte auch die selbe Einrückung haben.
Auch solltest Du einzelne Leerzeilen zwischen einzelnen Abschnitten lassen und nicht einen riesen Block leerer Zeilen einfügen. Eine Leerzeile reicht völlig aus um anzuzeigen, dass hier eine bestimmte Einheit endet und nun etwas anderes gemacht wird.


Zitat von altesfossil:
Hi,
1. Die Chromosomensätze, die es mir liefert, sollen in einer Datei gespeichert werden, weil ich die zu einem späteren zeitpunkt wieder brauchen werde.

2. ich sollte diese Datei überprüfen können, sie sollte also z.b. mit dem texteditor oder excel lesbar sein.
An sich sind diese beiden Punkte kein Problem. Du kannst hier auf beliebige Textformate (insbesondere auch eigene Varianten) zurückgreifen. Für Excel empfiehlt es sich, dass Du CSV-Dateien (Character Seperated Files) verwendest. Damit kannst Du die Datei direkt in Excel öffnen. Das Format ist denkbar einfach aufgebaut, jede Zeile in der Datei entspricht einer Zeile in der Tabelle. Die Zeile wiederum besteht aus Strings, die durch ein einfaches Trennzeichen (häufig Komma oder Semikolon) getrennt sind.

Code:
eintrag_1_1;eintrag_1_2;eintrag_1_3;...
eintrag_2_1;eintrag_2_2;eintrag_2_3;...
....
So sähe eine mögliche CSV-Datei aus. Empfehlen würde ich sie Dir für Dein Problem allerdings nicht.
Zu den üblichen Verdächtigen, die hier noch in Frage kommen dürften dann Ini-Dateien und XML-Dateien zählen. Für diese Formate gilt natürlich, dass sie sich nicht so schön in Excel anzeigen lassen. Der Vorteil an Ini-Dateien liegt darin, dass Delphi mit TIniFile und TMemIniFile bereits Kapselungen für dieses Format mitbringt. Dabei werden Datensätze in Sektionen abgelegt. Ein Datensatz besteht aus einem (für die Sektion) eindeutigen Schlüssel und einem Wert. Du kannst dann gezielt den Wert eines Datums auslesen/setzen, auf welche Du über die Sektion und den Schlüssel zugreifen kannst:
Code:
[Sektion1]
S1=Blubb
S2=Foo

[Sektion2]
s1=Blä
Hier könntest Du dann z.B. das Datum Sektion1, s1 auslesen und erhälst Blubb. Ist jetzt nur ein Beispiel, die Idee dürfte klar sein?!

Als letztes wie gesagt, bleibt noch XML. Dieses Format setzt auf Auszeichnungen (so genannte Tags). Die Tags werden dabei durch spitze Klammern dargestellt. Jedes Tag, dass geöffnet wird, muss auch wieder geschlossen werden (was das heißt siehst Du schon im Beispiel!).
Der Vorteil an XML ist, dass es mehr Strukturierung erlaubt als die anderen Formate. So können Tags beliebig geschachtelt werden, es darf aber nur ein oberstes Element geben:

Code:
<oberstesElement>
  <Individuum name="Blubb">
    <Teilpopulution>
      <Genotyp>
        <Chromosom1>
          <Value>0</Value>
          <Value>2</Value>
          <Value>1</Value>
          ....
          <Value>1</Value>
        </Chromosom1>
        <Chromosom2>
          <Value>0</Value>
          <Value>2</Value>
          <Value>1</Value>
          ....
          <Value>1</Value>
        </Chromosom2>
      </Genotyp>
      <Genotyp>
        <Chromosom1>
          <Value>0</Value>
          <Value>2</Value>
          <Value>1</Value>
          ....
          <Value>1</Value>
        </Chromosom1>
        <Chromosom2>
          <Value>0</Value>
          <Value>2</Value>
          <Value>1</Value>
          ....
          <Value>1</Value>
        </Chromosom2>
      </Genotyp>
    <Teilpopulution>
  </Individuum>
</oberstesElement>
Dieses Einrücken ist optional und soll nur die Lesbarkeit erhöhen. Die Idee ist halt, dass Du hier wieder eine Hierachie schaffst. Alles was zwischen dem öffnenden und schließenden Tag steht gehört zum jeweiligen Element. Ein Genotyp besteht hier z.B. aus den Tags Chromosom1 und Chromosom2. Diese stellen wiederum eigene Hierachien dar, denen 10 Value-Tags untergeordnet sind. Diese wiederum haben direkt einen Wert.
Der Vorteil von XML ist, dass Du hier eine Menge Werkzeuge findest, die Dir die Arbeit mit ihnen erleichtern. So kannst Du gibt es XML-Transformationen, die Dir zusammen mit einer solchen XML-Datei eine andere (leichter lesbare) Sicht erzeugen (XSLT) und Du kannst auch die Wohlgeformtheit eines XML-Dokuments prüfen (DTD oder XML-Schema). Willst Du also nur solche Dateien als valide ansehen, bei denen jeder Genotyp genau zwei Choromosomen mit je 10 Werten zwischen 0 und 2 hat, dann kannst Du das leicht mit automatisch prüfen lassen.

Deswegen ist mein klarer Tipp an Dich, dass Du auf XML zurückgreifst. Wie man mit CSV-Dateien, Inis oder XML arbeitet findest Du, wenn Du nach den Begriffen in der DP suchst.

Zitat von altesfossil:
3.es gibt N populationen, jede population hat eine bestimmte Anzahl k von Idividuen drin, z.b. 500. Jetzt soll nochmal ein array( teilpopulation) mit k Einträgen entstehen, welche k-mal den chromosomensatz von Population 1 beinhaltet, dann ein weiterer array mit dem chromosomensatz von Population 2, usw... bis N. Diese N arrays würde ich auch gerne in eine Datei schreiben. Auch diese Daten würde ich gerne überprüfen und ich muss sie später abrufen und umwandeln können. da die zu speichernden Records aus array[1..10] of integer bestehen, noch eine Frage: kann man diese einzelarrays auch in einen String[10] umzuwandeln? Wenn ja, wie geht das?
An sich ist die Antwort auf die letzte Frage auch die Antwort darauf, wie Du Text-Dateien erstellst (XML, Ini und CSV sind nur speziell formatierte Textdateien). Um aus einer Zahl einen String zu erzeugen wird Dir die Funktion IntToStr zur Verfügung gestellt. Diese ist in der Unit SysUtils definiert (mit uses SysUtils einbinden!).

Ja, such einfach erstmal nach einem der Formate und schau Dir an, wie man mit ihnen arbeitet. Ggf. kannst Du natürlich jederzeit weiter nachfragen.

Gruß Der Unwissende
  Mit Zitat antworten Zitat