Entwickler-Ecke

Sonstiges (Delphi) - Karteikartenprogramm


nl - Mi 27.10.10 12:34
Titel: Karteikartenprogramm
Hallo!
ich brauche Hilfe beim Erstellen eines Karteikartenprogramms in Delphi. Ich bekomme auf dieses eine Note die wie eine Kursarbeit zählt und da ich sehr schlecht in Informatik bin benötige ich unbedingt Hilfe da ich nicht nochmal einen Unterkurs bekommen möchte.
Der Lehrer hat uns generell nicht vieles gesagt woran wir uns halten sollen, also habe ich relativ viel Spielraum.
Ich habe nicht viele Kenntnisse von daher wäre es super wenn mir jemand unkompliziert helfen könnte.
Als erstes bräuchte ich eine "Rohform" wie ich allgemein eine Karteikarte erstmal erstellen kann, da ich einen Enstehungsprozess nebenbei formulieren muss.
Eine Karteikarte soll zb. mehrere englische Wörter enthalten die random aufgerufen werden sollen. Also zb. soll ein englisches Wort angezeigt werden sodass man in zb einem Editfeld die Übersetzung eingibt und dies soll dann überprüft werden ob es richtig oder falsch ist, somit soll also eine Ausgabe folgen.
Das Ganze soll objektorientiert sein, also auch in "public" und "private" gegliedert werden.
Ich habe ebenfalls keine Ahnung wie man eine Datenbank in Delphi erstellt, wo alle diese Karteikarten, sowie Antworten und Fragen enthalten sein sollen.

Ich hoffe mir kann jemand helfen, da ich wirklich sehr wenig Ahnung habe :/

Danke im Voraus.

MFG nl


MaxWurzel - Mi 27.10.10 13:22

Vielleicht hilft dir das hier weiter:
http://www.delphi-forum.de/viewtopic.php?t=79035&highlight=vokabeltrainer


Delete - Mi 27.10.10 13:55

Das einfachste wäre wahrscheinlich eine typisierte Datei. Jeder Record enthält dabei Frage und Antwort.


elundril - Mi 27.10.10 14:00

Und was dann die umsetzung in Delphi angeht:

Christians Crashkurs [http://www.christian-stelzmann.de/index_tutorials_crashkurs.html]
Delphi-Wikibook [http://de.wikibooks.org/wiki/Programmierkurs:_Delphi]
Typisierte Dateien [http://www.delphi-treff.de/tutorials/datenspeicherung/typisierte-dateien/einleitung/]

lg elundril


freedy - Mi 27.10.10 15:14

Hallo!

Hast du denn schon ein Konzept, wie du das Ganze aufbauen möchtest? Ich glaube, wenn du dir das erst einmal alles klarmachst, siehst du auch, was du wo und an welcher Stelle benötigst. Letztlich sollte dann das Programm rauskommen... ;-)

Manchmal hilft es, eine Art Drehbuch zu schreiben und zu zeichnen. Wenn du dann die einzelnen Skizzen noch in knappen Worten beschreibst, hast du zumindest schon einmal den groben Aufbau des Programms. Wenn du dann genaue Fragen hast, wie du etwas implementieren musst, wird dir hier sicherlich geholfen.

Grüße
Michael


Critter - Mi 27.10.10 16:43

Hallo,

ich würde auch wie user profile iconfreedy daran gehen. Gucke dir erst einmal an, was genau von euch verlangt wird. Du schreibst, das ihr "Objektorientiert" arbeiten sollt wie Objektorientiert "Objektorientiert" ist, hängt leider immer sehr stark vom Lehrer ab. Ich nehme einmal an, er erwartet, dass es irgendwo in deinem Programm eine Klasse tKarteiKarte geben muss? Dann würde ich damit anfangen, mir zu überlegen, wie diese aufgebaut sein muss und sie eventuell Programmieren (zu Testzwecken einfach mit einer beliebigen Vokabel füllen). Wenn diese Grundfunktion gegeben ist, würde ich mir erst Gedanken machen, wie ich das ganze Speichere und wie ich aus den vielen gespeicherten Karteikarten eine beliebige auswähle (vielleicht fällt dabei ja eine Klasse tKarteiKasten ab ;)).

Aber wie gesagt du musst die Anforderungen an deine Anwendungen eingrenzen und das "Objektorientiert" kann Leider alles heißen (mir sind da Lehrer untergekommen für die war das Kriterium ausreichend erfüllt, wenn es irgendwo ein tForm und ein tButton gab).

critter


Xion - Mi 27.10.10 16:46

Also eine Karteikarte besteht nach deiner Beschreibung aus folgendem:
- EIN englisches Wort (auch wenn du erst meinst es müssen mehrere englische Wörter drauf, das find ich unlogisch)

- EIN oder mehrere Übersetzungen

Dann machst du ein array von diesen Karteikarten (=Karteikasten). Dort kannst du dann random eine auswählen.

Speichern kann man das ganze dann relativ leicht. Am besten du legst die Werte erstmal im Code an und lagerst dann, wenn das Abfragen funktioniert, die Werte in Dateien aus. (Dann hast du nämlich schonmal was, wo du irgendeine "bessere" Note drauf erhalten kannst, auch wenn du keine Zeit mehr hattest, die Werte auszulagern). Auch das Einfügen von Karteikarten usw. wäre für mich Sekundär.

Eine Klasse für eine Karteikarte schreiben ist eigentlich einfach. Das beste ist, vor allem wenn du dir nicht so sicher bist, erstmal schriftlich als Strichliste zu notieren, was diese Karteikarte können müsste

UNGEEIGNETES Beispiel:
Eigenschaften
-Farbe
-Papiertyp
-Schriftart
Funktionen
-Zerknüllen
-AnDieWandHängen

Wenn du zeigst, dass du nicht nur fertigen SourceCode von uns willst, dann kriegst du sicher auch genauere Hilfe ;) Jeder hat Angst zu viel zu verraten, damit du nicht durch pures Kopieren eine anständige Note erhälst.


Critter - Mi 27.10.10 17:23

Hi,

@user profile iconXion: Das ist dann der Apple Ansatz. Nach dem Motto: Ich mache mir die Welt, wie sie mir gefällt. Wenn es bestandteil der Aufgabe ist, dass mehrere Englische Worte rein müssen, dann wird user profile iconnl sich auch dran halten müssen, sonst drückt das auf die Note. Unlogisch finde ich es übrigens gar nicht, im gründe könnte man sogar auf beiden Seiten mehrere Vokabeln zulassen, denn es kann ja durchaus sein, das eine Grupe Deutscher Synonyme einer Gruppe englischer Synonymen gegenübersteht. Aber das ist hier ja nicht die Aufgabe und Aufgaben umdefinieren ist meist Recht gefährlich für die Note.

So wie ich die Aufgabe bisher verstanden habe sollte es so laufen: Es Existieren mehrere Vokabelkarten, das Programm Pickt sich eine Karte hier heraus, diese enthällt immer eine Deutsche Vokabel und eine oder beliebig viele Englische Entsprechungen, nun wählt das Programm eines der Synonyme und zeigt es an, der Benutzer muss nun die (einzige) deutsche Vokabel eingeben. Das ist weder unlösbar noch unsinnig, somit rate ich dringend davon ab mal eben zu sagen, dass die Karte nur eine Englische Vokabel enthält. Besonders da der der Lehrer sich sicherlich etwas dabei gedacht hat (und in diesem Fall meine ich sogar etwas nachvollziehbares) ;).

critter


nl - Mi 27.10.10 19:51

Erstmal vielen Dank für die schnellen und vielen Antworten.

Ich möchte ja selbst kein copy & paste ;) würde es gerne verstehen.

Also ich habe nochmal genau geschaut, der Lehrer hat mir heute auch nochmal ein paar Dinge genannt:

TKarte:
Frage: string
Antwort: string
(Er hat noch etwas von "getRueckseite","getVorderseite" geredet, leider versteh ich das nicht so wirklich :/)


TStapel:
array of Karte(Anzahl)

und dann soll noch ein "Verwalter" vorhanden sein in dem quasi alles überprüft wird.

Also eine Karte soll ein Wort zum übersetzen enthalten, sowie ein Eingabefeld und ein Label zum ausgeben.

Wenn mir jemand "getRueckseite/Vorderseite" erklären würde wär es gut, dann könnte ich mal einen Ansatz probieren.


Danke.
MFG nl


Delete - Mi 27.10.10 19:56

Na ja, auf der richtigen Karteikarte aus Pappe steht auf der Vorderseite die Vokabel und auf der Rückseite die Übersetzung. Die gibt es so natürlich nicht im Code. Das war nur sinnbildlich gemeint vom Lehrer, um einen Bezug zur Wirklichkeit herzustellen.


nl - Do 28.10.10 13:42

Ich könnte mir wirklich den Kopf zerbrechen und komm keinen Meter voran. Habe echt keinen Plan wie ich überhaupt anfangen muss...

Ich weiß nicht wie ich das mit Frage, Antwort mache, bz. wie ich denen eben eine "Frage" zuteile und das anzeigen lasse :/

Verzweifel hier bald :o

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Muss denn Frage und Antwort eine Function od. eine Procedure sein?


freedy - Do 28.10.10 14:01

Hallo nl!

Hör mal auf, zu implementieren, also Code zu schreiben. Wenn dein Konzept nämlich steht, ergibt sich das quasi von alleine. Das Programmieren ist ja nur eine Sprache. Wenn du in einer Stadt im Ausland irgendwohin möchtest, fragst du dich doch auch als erstes, was du jemanden überhaupt fragen willst, BEVOR du dir den Satz im Kopf übersetzt. Mir geht es jedenfalls so.

Präsentiere uns doch mal dein Konzept! Das ist, wenn ich das oben richtig gelesen habe, schließlich auch Bestandteil deiner Note.

Grüße


nl - Do 28.10.10 14:53

Also wie ich schon gesagt hatte soll TKarte EINE Vokabel zum Übersetzen besitzen und MEHRERE Übersetzungen ( da es ja meistens mehrere Übersetzungen für eine Vokabel gibt).

Also:
1. Label: Vokabel
2. EditFeld zur Eingabe.
3. Label: Richtig!/Falsch!
4. Label(falls Falsch!): Richtige Antwort:"..."
5. Button: Prüfen
6. Button: Nächste Vokabel

TKartenstapel soll alle Karten in sich haben(Array) und eine Random beim Start rauspicken und die Vokabel direkt anzeigen(dies geht mit Konstruktoren oder?).

Im "Verwalter" soll nun alles überprüft werden(sobald der "Button: Prüfen" geklickt wird), also ob die eingebene Übersetzung mit der Eingetragenen übereinstimmt und anschließend die Ausgabe in den vorgegebenen Labels stattfinden. Nach dem klicken des "Button: Nächste Vokabel" soll via Destruktor diese Vokabel im Speicher wieder überschrieben werden und logischerweiße die nächste Vokabel(Random) angezeigt werden, dann beginnt das ganze von Vorne.
(Verhindert der Destruktor dass die gleichen "Karten" hintereinander kommen? Wenn nicht die kann man das realisieren?)


Hab jetzt nur mal eine Grundform erstellt, den äußerlichen Feinschliff kann man ja immernoch gestalten :)

Habe mal ein Screen angehängt.

Hoffe dies hilft jetzt evtl.


platzwart - Do 28.10.10 14:56

Prozedur: Block von Befehlen, es wird zwar 'was gemacht' aber kein Ergebnis zurückgeliefert.
Funktion: Siehe Prozedur, jedoch wird ein Ergebnis zurückgeliefert.

Z.B. könnte man eine Prozedur verwenden, um einen String in einem Label anzeigen zu lassen. Dazu würde man der Prozedur als Paramter den anzuzeigenden String mit übergeben. Die Prozedur "berechnet" aber kein Ergebnis und gibt daher auch nix zurück.

Anders wäre es bei einer Funktion wie z.B. "Summe(Zahl1: Integer, Zahl2: Integer): Integer; Die Funktion bekommt zwei Ganzzahlen als Parameter und gibt das Ergebnis "Summe" als Ganzzahl wieder zurück.


platzwart - Do 28.10.10 14:59

Das schaut doch schonmal gut aus ;)

Nun hast du oben ja schonmal angefangen aufzuschreiben, wie TKarte und TStapel ausschaun sollen. Fang doch bei TKarte an und schreib deine abstrakte sprachliche Beschreibung mal in Delphi ;)


freedy - Do 28.10.10 15:20

Dein Projekt schreit ja förmlich nach MVC. Sagt dir das etwas? Wahrscheinlich nicht. Ich habe so etwas damals in der Schule jedenfalls nicht gelernt. Aber das ist ja erstmal egal. ;-)

MVC steht für Modell, View und Control. Das heißt letztlich nichts anderes, als dass die Daten - in deinem Fall die Vokabelkärtchen - von der Anzeige getrennt vorliegen sollen. Das umgehst du letztlich, indem du alle Kärtchen, jedes in seine eigene, Struktur steckt. Okay, wir brauchen also eine Struktur. In Delphi nennt man soetwas Record. An dieser Stelle solltest DU DIR überlegen und uns nachher präsentieren, wie du dir die Struktur vorstellst. Platzwart hat das ja schon angeführt. Da es nicht nur ein Kärtchen gibt, müssen diese Kärtchen irgendwo gesammelt und zu einer Menge vereinigt werden. Du brauchst also eine Liste. Das alles wäre dann irgendwo dein Modell.

Jetzt schauen wir uns einmal die View an. Die Aufgabe der View ist nur, die Daten aus dem Modell darzustellen. Sie führt keine Überprüfung durch und trägt auch keine neuen Daten ein. Sie stellt nur dar! Damit sind und bleiben die Daten immer von der Darstellung unabhängig. Für viele Projekte ist das sehr wichtig.

Das Herzstück für dein Vokabelprogramm ist dann der Controller. Er verbindet Modell und View miteinander. Wenn du in dem Formular ein Eingabefeld hast, wird der eingetragene Text an den Controller übergeben. Dieser vergleicht die Eingabe mit der erwarteten Eingabe; denn er kennt auch die Daten und weiß, welche Karte gerade ausgewählt wurde. Der Controller gibt dir auch die Antwort zurück, ob die Eingabe richtig oder falsch war. Die View dann kann darauf reagieren und eine entsprechende Ausgabe machen, so wie das schon von dir vorgeschlagen wurde.


Vielleicht wird dir jetzt auch klar, dass das, was du oben beschrieben hast, dann keine optimale Lösung ist. Es geht, würde auch irgendwie funktionieren. Alternativ schlage ich dir den Entwurf einer neuen Klasse vor, die eben alles erledigt, was der Controller zu tun hat. Du kannst sie einfach in deine Applikation einbinden. Dein Modell, also die Kärtchen, könntest du auch in eine separate Klasse auslagern. Damit erfüllst du dann die Aufgabenstellung, dass es objektorientiert sein soll.

Das Ganze solltest du dir aufmalen. Und damit meine ich nicht, wie und wo irgendwelche Komponenten auf dem Formular platziert werden. Male dir auf, welche Daten wo und in welcher Form benötigt werden. Wenn du dabei noch Hilfe brauchst, frag einfach.


nl - Do 28.10.10 15:58

Ja die 3 sollen aufjedenfall jeweils eine eigene Klasse sein.
Mein Problem ist einfach dass ich nicht weiß welche Daten ich in welcher Form brauche, mir fehlen einfach total die Grundlagen da ich letztes Jahr einen ziemlich unfähigen Lehrer hatte.

Ich habe noch nie etwas von "Record" gehört und von Listen weiß ich leider auch sehr wenig.

Eigtl. versteh ich ja was ihr mir vorschlagt, aber iwie krieg ich es nicht auf die Reihe, es auf "Papier" zu bringen, auch gerade weil mir diese Grundlagen fehlen.

Hoffe ihr hattet schon öfter mit Personen wie mir zu tun :D


freedy - Do 28.10.10 16:29

Dann solltest du zumindest einen der Crashkurse durcharbeiten (s. Beitrag von user profile iconelundril)

user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:


Christians Crashkurs [http://www.christian-stelzmann.de/index_tutorials_crashkurs.html]
Delphi-Wikibook [http://de.wikibooks.org/wiki/Programmierkurs:_Delphi]
Typisierte Dateien [http://www.delphi-treff.de/tutorials/datenspeicherung/typisierte-dateien/einleitung/]



Xion - Do 28.10.10 18:10

Also, ich fass das von user profile iconfreedy nochmal zusammen *schlagt mich wenns falsch ist*


View: Die Schnittstelle mit dem User
Drückst du auf einen Knopf, wird der "Klasse" View mitgeteilt, dass der Knopf gedrückt wurde. (wäre diese Klasse nicht die TForm?). Die View leitet dann die Anfrage, was auf diesen Knopfdruck passiert, an den Controller.

Controller: Verbindung von View zu Modell
Kriegt der Controller eine Anfrage, so sucht er die entsprechenden Daten raus. (wie weit ist denn hier die Abstraktion? Kann er gleich in die Daten zugreifen, oder macht das das Modell?)

Modell: Der Daten-Speicher
(Ist ein record eine Klasse? Eigentlich nicht. Von daher bräuchten wir garkein record)


Also meiner Auslegung nach wäre die View die Form, und das Modell wäre ein array of Karteikarte. Der Controller ist das Paket an Funktionen, in denen das eigentliche Programm steckt (Vergleiche machen, Ergebnis ausgeben usw.)

Ist das so richtig? :lol:
Wie man sieht ist mir dieses Prinzip noch nicht beigebracht worden (3.Semester Informatik). Ich glaube der Lehrer hat das so nicht gemeint ;) Scheint mir sehr hoch gegriffen.


platzwart - Do 28.10.10 20:45


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
type

TPerson: record
           Vorname: String[20];
           Nachname: String[50];
           Alter: Integer;
           Verheiratet: Boolean;
         end;


Verinnerliche dir mal dieses Beispiel eines Records. Anschließend überlegst du, wie dein Record ausschaun sollte und poste es hier ;)


nl - Do 28.10.10 22:12

Was bedeuten die Zahlen in den Klammern :)?

Ja bin die Crashkurse am durchgehen :)


elundril - Do 28.10.10 22:15

Das ist die Länge des Strings. Damit man Strings auch in typisierten Daten speichern kann, muss man ihnen eine fixe Länge zuweisen (eben durch die zahlen in den Klammern).

lg elundril


Delete - Fr 29.10.10 01:38

Eventuell wäre noch das Tutorial von mir interessant: http://www.michael-puff.de/Programmierung/Delphi/Tutorials/Container-Klassen/


freedy - Fr 29.10.10 09:08

user profile iconXion hat folgendes geschrieben Zum zitierten Posting springen:
Also, ich fass das von user profile iconfreedy nochmal zusammen *schlagt mich wenns falsch ist*


muss dich nicht schlagen ;-)

Es hat mich doch irgendwie nicht losgelassen. Google spuckte mir folgende Seite aus: http://oszhdl.be.schule.de/gymnasium/faecher/informatik/delphi/mvc.htm

Nur, falls es noch jemanden interessiert.


Die Beschreibung der Container-Klassen von user profile iconLuckie ist wirklich gut und verständlich geschrieben. Es lohnt sich auf jeden Fall, sie wenigstens einmal zu lesen.


freedy - Mi 03.11.10 16:10

Hallo NL,

was ist denn nun eigentlich aus deinem Projekt geworden? Bist du fertig?

Grüße


nl - Mi 03.11.10 18:45

Sorry habe zur Zeit viel zu tun.
Habe wenn ich Zeit hatte paar Crashkurse durchgearbeitet, melde mich demnächst mochmal wenn ich wieder mehr Zeit habe.

Danke.


nl - Di 09.11.10 11:48

Hallo wiedereinmal,
hatte wenig Zeit und konnte deswegen kaum weiter arbeiten.
Muss die vorgegebene Länge exakt mit der des Strings entsprechen?


Habe mal was angefügt...wäre das so einigermaßen richtig?


nl - Di 09.11.10 12:04

user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
http://www.michael-puff.de/Programmierung/Delphi/Tutorials/Container-Klassen/


Bin ich mal durchgegangen, wäre doch eigtl auch relativ sinnvoll bei meiner Aufgabe oder?
Leider versteh ich viele sachen nicht...Woher weiß denn das Progamm "was" die Karte denn überhaupt für einen Wert oder sonstiges bekommt bei "FCards.Add(Card);" und was "function GetItem(Index: Integer): TCard;
procedure SetItem(Index: Integer; const Value: TCard);"
bewirkt weiß ich auch nicht :o


platzwart - Di 09.11.10 12:22

Ohne mir den Quelltext anzuschaun, würde ich das wie folgt interpretieren:

function GetItem(Index: Integer): TCard;
Du willst eine Karte vom Stapel haben, nämlich die an der Position 'Index'. Es wird eine Karte des Typs TCard zurückgegeben ('function' gibt immer etwas zurück).

procedure SetItem(Index: Integer; const Value: TCard);
Du willst eine Karte dem Stapel hinzufügen. Es handelt sich dabei um die Karte 'Value' vom Typ TCard. Die Karte wird an die Position 'Index' gelegt ('procedure' geben nie etwas zurück).

FCards.Add(Card);
Fügt dem internen Kartenstapel die Karte 'Card' hinzu.


platzwart - Di 09.11.10 12:28

user profile iconnl hat folgendes geschrieben Zum zitierten Posting springen:
Hallo wiedereinmal,
hatte wenig Zeit und konnte deswegen kaum weiter arbeiten.
Muss die vorgegebene Länge exakt mit der des Strings entsprechen?


Habe mal was angefügt...wäre das so einigermaßen richtig?


Ja, schaut gut aus, darauf kann man aufbauen. Nein, die Längenangabe ist nur die Maximallänge. Bitte hänge solch kleine Quellcodetexte nicht an, sondern poste sie direkt hier wie folgt:


Quelltext
1:
<span class="inlineSyntax"><span class="codecomment">{PROTECTTAGf9258d87807ae2feb8b8b8274a3dbdd4}</span></span>                    


Dann schaut das ganze so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
type

TKarte: record
         Frage: String[10];
         Antwort: String[50];
         Uebersetzung: Boolean;
        end;


nl - Di 09.11.10 12:50

Okay gut. Also wäre das jetzt quasi eine meiner Karten.
Meine nächste Frage wäre dann, wie ich Frage, bzw Antwort etw. zuweisen kann, habe ja noch nie mit "record's" gearbeitet.



Delphi-Quelltext
1:
test ;)                    


bummi - Di 09.11.10 13:38


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
type
TKartenArray=Arry of TKarte;
private
FKartenArray:TKartenArray;
....
begin
Setlength(FKartenArray,10);

FKartenArray[0].Frage := '1. Frage';
FKartenArray[0].Antwort := '1. Antwort';
...
FKartenArray[9].Frage := '10. Frage';
FKartenArray[9].Antwort := '10. Antwort';
...


platzwart - Di 09.11.10 13:47

Du solltest jedoch beachten, dass der Teil von SetItem/GetItem OOP ist, die Array/Record Geschichte jedoch nicht, es sind also zwei verschiedene herangehensweisen.


nl - Di 09.11.10 17:07

Ja ich denke das ist okay, der Lehrer hat ja selbst Arrays für den "Verwalter" vorgeschlagen.
Noch eine Frage, wenn ich das nun mit einem "Verwalter", den einzelnen Karten und dem "Kartenstapel" machen will, wie realisier ich das?
weil so wären ja die Karten im "Kartenstapel" deklariert oder?


platzwart - Di 09.11.10 17:23

Ehm... ne... Du erstellst ein Record. Dieses Record ist der Prototyp deiner Karten, also nur die Beschreibung, wie eine Karte ausschaun soll, aber es ist keine Karte an sich. Darüberhinaus musst du separat den "Verwalter" anlegen, der ist unabhängig von den Karten an sich. Der nimmt die Karten auf (Array of TKarte...) und besitzt so Methoden wie z.B. 'KarteEinfügen(Index, Karte)', 'KarteLöschen(Index)', 'KarteZiehen: Karte'.


freedy - Di 09.11.10 17:49

Hallo NL,

alternativ könntest du folgendes machen.

Du baust dir eine Collection. Das ist eine Klasse, die die Fähigkeit hat, eine beliebige (je nach Speicher) Menge von anderen Objekten zu verwalten. Das solltest du in dem Tutorial von Luckie gelesen haben. Dann ist allerdings jede Karte ein Objekt. Das macht aber nichts, denn dadurch gewinnst du mehr Möglichkeiten.

Das Ganze funktioniert dann so:

1. Du erzeugst dir eine Klasse TCard. Diese ist die Beschreibung für eine Karte.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
TCard = class(TCollectionItem)
private 
  FFrage : String;
  FAntwort : String;
public
  function Prüfe(BenutzerAntwort : String) : Boolean;
  property Frage : String read FFrage write FFrage;
  property Antwort : String read FAntwort write FAntwort;
end;


2. Du erzeugst dir eine Klasse TCards. Diese sammelt alle deine Karten. Um die Klasse TCollection nutzen zu können, musst du "Classes" in die Uses aufnehmen, wenn noch nicht geschehen.


Delphi-Quelltext
1:
2:
3:
 
TCards = class(TCollection)
end;



Deine Klasse TCard sieht nun fast genauso aus, wie dein Record. Allerdings bist du hier nicht auf Längen beschränkt (das, was du vorher in den eckigen Klammern schreiben musstest).

3. Wir müssen der Klasse TCards nun mitteilen, welchen Typ sie verwalten soll. Sie hat, wie jede andere Klasse einen Konstruktor. Diesen "klauen" wir uns jetzt und überschreiben ihn.


Delphi-Quelltext
1:
2:
3:
4:
5:
 
TCards = class(TCollection)
public
  constructor Create; reintroduce;  
end;


Das reintroduce bedeutet eigentlich nicht mehr, als dass die Methode neu eingeführt wird, obwohl sie bereits vorhanden ist.

4. In der Implementierung schreibst du nun folgendes:


Delphi-Quelltext
1:
2:
3:
4:
5:
 
constructor TCards.Create;
begin 
  inherited Create(TCard);  
end;


Die Zeile "Inherited Create" ruft nun die alte Methode Create auf und sagt der Collection, dass sie nun die Klassen vom Typ TCard verwalten soll.


5. Als nächstes brauchen wir eine Methode, um eine neue Karte anzulegen. Dazu erweitern wir die Klasse TCards um eine Funktion Add. Deine Klasse sollte jetzt so aussehen:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
 
TCards = class(TCollection)
public
  constructor Create; reintroduce;  

  function Add : TCard;
end;


Und hier die Implementierung:


Delphi-Quelltext
1:
2:
3:
4:
5:
 
function TCards.Add : TCard;
begin 
  Result := TCard(inherited Add);  
end;



6. So weit, so gut. Du bist jetzt sicherlich gespannt, ob das schon so funktioniert. Testen wir es:

Baue in ein Formular einfach eine Variable in den Public-Bereich ein "Cards : TCards;". Im FormCreate (s. Ereignisse des Formulars, ggf. Suche) kannst du dann die Instanz anlegen. Dazu musst du dort nur folgende Zeile einfügen "Cards := TCards.Create;". Im FormDestroy solltest du, damit es sauber programmiert ist, das Objekt auch wieder mit "Cards.Free" bzw. "FreeAndNil(Cards);" freigeben.

Jetzt können wir erstmal einen Button und ein Label auf das Forumlar legen. Das OnClick-Ereignis des Buttons sollte den folgenden Quelltext enthalten (ggf. anpassen):


Delphi-Quelltext
1:
2:
  Cards.Add;
  Label1.Caption := 'Cards enthält ' + IntToStr(Cards.Count) + ' Karten.';


Magst du das erst einmal probieren? Der Rest ist dann sehr einfach.

Grüße


nl - Mi 10.11.10 13:15

property Frage : String read FFrage write FFrage;
property Antwort : String read FAntwort write FAntwort;


kann mir evtl jemand diese Zeile erklären?


Xion - Mi 10.11.10 13:19

Eine "property" ist ein Attribut zu Deutsch. In Delphi hat man den Luxus, dass man keine Getter und Setter schreiben muss, sondern (obwohl die Variable eigentlich private ist) trotzdem "direkt" darauf zugreifen kann, wenn man keine Getter/Setter-Funktionen benötigt.


Im Wesentlichen heißt es:

Wenn du "Frage" lesen willst, dann geb ich dir den Inhalt aus "FFrage"
Wenn du "Frage" schreiben willst, dann schreib ich das in "FFrage"

Man könnte in diesem Beispiel FFrage auch einfach public machen. Allerdings ist es so leicht abänderbar:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
property Frage : String read FFrage write SetFrage; 

procedure SetFrage(V: String);
begin
  FFrage:='Bla'+V;
end;


So würde immer, wenn du in Frage was schreibst, erst noch "Bla" davor gehängt.


nl - Mi 10.11.10 13:21

wäre dieser Aufbau jetzt in einer einzigen Unit?


elundril - Mi 10.11.10 13:23

Du könntest es alles in eine Unit schreiben. Delphi verträgt auch mehrere Klassen in einer Unit.

lg elundril


nl - Mi 10.11.10 13:36

Wie weise ich bei Property "FFrage" etwas zu? So wie ich das sehe ist da ja keine procedure dabei oder?

Wenn ich es in unterschiedliche Units machen möchte, wie teile ich das am besten auf?
Muss ja OOP bleiben, oder hat das garnichts damit zutun :D?


freedy - Mi 10.11.10 13:41

user profile iconnl hat folgendes geschrieben Zum zitierten Posting springen:
Wie weise ich bei Property "FFrage" etwas zu? So wie ich das sehe ist da ja keine procedure dabei oder?


FFrage ist kein Property. Das Property ist Frage. Die Zuweisung ist dann:


Delphi-Quelltext
1:
 Card.Frage := 'Wie heiße ich?';                    


user profile iconnl hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich es in unterschiedliche Units machen möchte, wie teile ich das am besten auf?
Muss ja OOP bleiben, oder hat das garnichts damit zutun :D?


Die Aufteilung der Klassen in Units in unabhängig von OOP. Du kannst auch alles in eine Unit bzw. Datei schreiben. OOP heißt nur, dass du mit Objekten arbeitest. Die erzeugst du dir ja bspw. mit den Klassen TCard.

Nachtrag: evtl. könntest du dein Projekt schon eimal online stellen. Dann sehen wir, was du wie machst.


nl - So 14.11.10 19:48

Also, der Lehrer hat uns ein wenig geholfen und das herausgearbeitet:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
unit UKarte;

interface

type TKarte = class
  private
    Vorderseite: string;
    Rueckseite: string;
  public
    function getVorderseite: string;
    function getRueckseite: string;
    constructor create(V,R: string);
  end;

implementation

function TKarte.getVorderseite: string;
begin
   result:=Vorderseite;
end;

function TKarte.getRueckseite: string;
begin
   result:=Rueckseite;
end;

constructor TKarte.create(V,R: string);
begin
   inherited create;
   Vorderseite:= V;
   Rueckseite:= R;
end;

end.



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
unit UKasten;

interface

uses UKarte;

type TKasten = class
   private
      n : integer;
      st : array of TKarte;
   public
      function getKarte(k: integer): TKarte;
      procedure add(k: TKarte);  overload;
      procedure add(V,R: string); overload;
   end;

implementation

function TKasten.getKarte(k: integer): TKarte;
begin
  if k<n then result:=st[k]
         else result:=TKarte.create('-''0');
end;

procedure TKasten.add(k: TKarte);
begin
   n:=n+1;
   Setlength(st, n);
   st[n-1]:=k;
end;

procedure TKasten.add(V,R: string);
var k: TKarte;
begin
   k:=TKarte.create(V,R);
   add(k);
end;


end.


Wie füge ich jetzt einer Karte was zu? Das versteh ich nich ganz. Und wie verbinde ich das mit ButtonOnClick ?

:)


freedy - Mo 15.11.10 17:57

Hallo NL!

Das, was euer Lehrer da gemacht hat, funktioniert zwar; aber ich finde das gruselig.

Verstehst du, was dort gemacht wird und warum?

Beim Programmieren geht es eigentlich nicht darum, immer nur Programmcode zu tippen. Man sollte auch nachdenken und Lösungen, die schon einmal gefunden wurden, wieder benutzen. Das tut euer Lehrer nicht. Nun kenne ich seine Hintergründe nicht und weiß nicht, ob er mit dieser Art irgendwas bezwecken will.

In deinem Formular erzeugst du dir nun eine Instanz von TKasten. Von dieser Instanz rufst du einfach die Funktion Add auf. Wie das alles geht, solltest du in den Crashkursen gelesen haben. Deshalb verwundert mich eigentlich deine Frage auch ein wenig.

Da du dich bei dem Code von deinem Lehrer auch um die gesamte "Speicherverwaltung" kümmern musst, achte darauf, dass beim Beenden des Programms auch wieder alle Instanzen freigegeben werden. Als Erinnerung hilft es, wenn du bspw. in das OnCreate des Formular diese Zeile mit hinein nimmst.


Delphi-Quelltext
1:
  ReportMemoryLeaksOnShutdown := true;                    


Grüße


nl - Mo 15.11.10 22:35

Hm ja der Lehrer macht das eigtl meistens so...Weiß nicht ob jmd "Chuck a Luck" kennt aber das haben wir ähnlich programmiert, ehrlich gesagt klingen eure Lösungen besser, aber ich hab nicht mehr viel Zeit und da die Note wichtig ist sollte ich schnellstmöglich fertig werden auch wenn ich nicht alles genaustens verstehe. Habe also leider nicht mehr viel Zeit daran rum zu feilen :/


nl - Mi 17.11.10 14:27

Ich versteh einfach überhaupt nicht wie ich jetzt einen "verwalter" mache der die Inhalte der Karten speichert und diese Random aufruft. Was passiert denn überhaupt bei Add? Es kommt eine Karte dazu? Und woher weiß das Programm was diese Karte besitzt? Lediglich Vorder und Rückseite oder? Weiß garnicht wie ich realisieren soll dass jetzt Vorder bzw Rückseite rnd iwas zugewiesen bekommt :(


freedy - Mi 17.11.10 15:57

Das hier wir dir persönlich garantiert nicht helfen; geschweige denn, dass ich glaube, dass du dadurch etwas lernst.

Ich habe dir mal schnell ein Programm zusammengeschrieben. Vielleicht steigst du da ja durch. Du solltest dir allerdings überlegen, ob es so schlau war, Informatik zu belegen. Wir haben dir hier nun ziemlich viele Hilfen gegeben. Die Tutorials scheinst du - meiner Ansicht nach - nicht durchgearbeitet zu haben. Sorry...


nl - Di 30.11.10 16:38

Ich habe Informatik belegt weil ich in Latein, Chemie und Physik eine totale Niete bin.
Ganz ehrlich seit dem ich mich hier angemeldet habe habe ich mehr gelernt als in den 2 Jahren Informatik die ich hatte ;)


freedy - Di 30.11.10 16:55

Hast du die Aufgabe denn inzwischen bewältigen können?