Page 1 of 2
Oberon Test Examen oefening
Posted: Fri Dec 23, 2005 12:36 pm
by Nickman
Ik ben is een testoefening voor examen aan't maken (Dirk heeft ze mij gegeven

) maar nu heb ik probleempje met OO lijst...
In de AddProducts procedure zelf is alles in orde, maar vanaf dat ik mijn lijst buiten de Add procedure meegeef aan PrintLijst dan is hij ineens leeg
Code: Select all
MODULE TestExamen;
IMPORT
In, OutExt, Strings;
TYPE
LIST* = POINTER TO LISTDESC;
LISTDESC* =
RECORD
prev*: LIST;
code*: INTEGER;
naam*: ARRAY 30 OF CHAR;
prijs*: REAL;
aantal*: INTEGER;
next*: LIST;
END;
PROCEDURE (L : LIST) BeginNewList*;
BEGIN
NEW(L);
L^.next := NIL;
L^.prev := NIL;
END BeginNewList;
PROCEDURE (L : LIST) AddProducts*;
VAR
new, current: LIST;
BEGIN
In.Open();
NEW(new);
In.Int(new^.code);
In.String(new^.naam);
In.Real(new^.prijs);
In.Int(new^.aantal);
IF (L^.code = 0) & (L^.naam = "") & (L^.prijs = 0) & (L^.aantal = 0) & (In.Done) THEN
L := new;
END;
current := L;
WHILE (In.Done) DO
current^.next := new;
new^.prev := current;
current := current^.next;
current^.next := NIL;
NEW(new);
In.Int(new^.code);
In.String(new^.naam);
In.Real(new^.prijs);
In.Int(new^.aantal);
END;
L^.PrintLijst;
END AddProducts;
PROCEDURE (L : LIST) PrintLijst;
VAR
current: LIST;
length: LONGINT;
BEGIN
IF (L^.code = 0) & (L^.naam = "") & (L^.prijs = 0) & (L^.aantal = 0) THEN
OutExt.String("Nog geen Producten toegevoegd");
ELSE
OutExt.String(" Code | Produkt | eh prijs | aantal"); OutExt.Ln;
OutExt.String("------+--------------------------------+----------+-------"); OutExt.Ln;
current := L;
REPEAT
OutExt.Int(current^.code,5);
OutExt.String(" | ");
OutExt.String(current^.naam);
length := Strings.Length(current^.naam);
WHILE (30 - length) # 0 DO
OutExt.String(" ");
INC(length);
END;
OutExt.String(" | ");
OutExt.RealFix(current^.prijs, 8, 2);
OutExt.String(" | ");
OutExt.Int(current^.aantal, 6);
current := current^.next;
OutExt.Ln;
UNTIL (current = NIL);
END;
END PrintLijst;
PROCEDURE Test*;
VAR
lijst: LIST;
BEGIN
NEW(lijst);
lijst^.BeginNewList;
lijst^.AddProducts;
lijst^.PrintLijst;
END Test;
BEGIN
OutExt.Open();
OutExt.Clear;
END TestExamen.
Posted: Fri Dec 23, 2005 1:03 pm
by EagleEye812
By the way het is deze oefening
KLIK
Posted: Fri Dec 23, 2005 2:46 pm
by Norfolk
EagleEye812 wrote:By the way het is deze oefening
KLIK
vanwaar gehaald?

Posted: Fri Dec 23, 2005 3:05 pm
by EagleEye812
Posted: Fri Dec 23, 2005 3:09 pm
by Nickman
Niemand een idee aan wat dit kan liegen?
Posted: Fri Dec 23, 2005 3:57 pm
by Yo_rik
Een receiver is een waardeparameter, die wijzigingen aan de beginpointer van uw lijst worden dus niet teruggegeven.
Ik denk dat het beter is om een globale variabele te gebruiken voor het begin van de lijst, zodat ge vanuit het Toolbestand de afzonderlijke functies kunt gebruiken, zonder dat de lijst verloren gaat. Zo is ook uw probleem opgelost

.
Posted: Fri Dec 23, 2005 3:57 pm
by Shinta
Hmm bij al die examens heb je zo vaak dage een OXO spelleke moet maken of andere spellekes, maar ge kunt in oberon toch geen interactieve input geven, da moet je toch vooraf in je parameterlijst zetten.
Moet ge dit dan verhelpen door zoals den arickx soms zo tijdens het runnen bepaalde procedures te laten draaien, ééntje per keer, in plaats van dit allemaal vooraf te definiëren in een TestModule ?
De vragen zijn wel ni simpel though ...
Posted: Fri Dec 23, 2005 4:06 pm
by Yo_rik
Interactieve input gaat wel

, met module Input (zie Watson.ShowDef Input~

).
Die geeft alleen acties van toetsenbord of muis, dus omzetten van karakters naar bvb. integer moeten we zelf doen.
Posted: Fri Dec 23, 2005 4:19 pm
by Shinta
Yo_rik wrote:Interactieve input gaat wel

, met module Input (zie Watson.ShowDef Input~

).
Die geeft alleen acties van toetsenbord of muis, dus omzetten van karakters naar bvb. integer moeten we zelf doen.
och zwans ... swel iet handig
Posted: Fri Dec 23, 2005 4:26 pm
by Nickman
Yo_rik wrote:Een receiver is een waardeparameter, die wijzigingen aan de beginpointer van uw lijst worden dus niet teruggegeven.
Ik denk dat het beter is om een globale variabele te gebruiken voor het begin van de lijst, zodat ge vanuit het Toolbestand de afzonderlijke functies kunt gebruiken, zonder dat de lijst verloren gaat. Zo is ook uw probleem opgelost

.
Maar als ik nu OO porgrameer met matrixen bv. dan worden die matrices dat ik mee geef wel aangepast.
Waarom dan niet bij deze lijst?
Posted: Fri Dec 23, 2005 4:33 pm
by Yo_rik
Bij matrices verandert ge niet het adres (pointer) van de matrix, alleen de getallen die erin opgeslagen zijn.
Hier verandert het adres van het begin van de lijst telkens er een product wordt toegevoegd.
Het werkt dus eigenlijk hetzelfde als met gewone procedures, waar ge uw object als waardeparameter meegeeft

.
Posted: Fri Dec 23, 2005 4:47 pm
by Norfolk
Ge moet trouwens uw lijst gesorteerd op code afdrukken (vraag 2) dus ge moet ergens nog een sorteeralgoritme gebruiken.
Of zorgen dat bij het toevoegen van een produkt ineens op volgorde wordt toegevoegd
Posted: Fri Dec 23, 2005 4:51 pm
by Nickman
Ja, da van die volgorde da is altijd achteraf mogelijk he.
Maar het is dus onmogelijk om met een object geörienteerde lijst te werken :p.
Dan gebruik ik wel globale variabele....
Posted: Fri Dec 23, 2005 5:30 pm
by EagleEye812
De mijne werkt met VAR parameters dus niet met OO
Code: Select all
MODULE Kleinhandel;
IMPORT
In, OutExt, Files, Strings;
TYPE
Lijst* = POINTER TO LijstDesc;
LijstDesc* =
RECORD
previous: Lijst;
code: INTEGER;
naam: ARRAY 32 OF CHAR;
prijs: REAL;
aantal: INTEGER;
next: Lijst;
END;
PROCEDURE Initialise*(VAR L: Lijst);
(*
Omschrijving : Initialiseert een nieuwe lijst.
Parameters : L: Lijst die ge’nitialiseerd moet worden
Returntype : -
Algoritme : OO, dubbel gelinkte lijst
*)
BEGIN
NEW(L);
L^.previous := NIL;
L^.code := 0;
L^.naam := "";
L^.prijs := 0.0;
L^.aantal := 0;
L^.next := NIL;
END Initialise;
PROCEDURE AddProduct*(VAR L: Lijst);
(*
Omschrijving : Product toevoegen aan de lijst.
Parameters : L: Lijst
Returntype : -
Algoritme : OO, dubbel gelinkte lijst
*)
VAR
new: Lijst;
temp: Lijst;
duplicate: BOOLEAN;
BEGIN
IF L = NIL THEN
Initialise(L);
END;
In.Open();
WHILE (In.Done) DO
NEW(new);
duplicate := FALSE;
In.Int(new^.code);
In.String(new^.naam);
In.Real(new^.prijs);
In.Int(new^.aantal);
(* Check for duplicates *)
temp := L;
WHILE L # NIL DO
IF new^.code = L^.code THEN
duplicate := TRUE;
L^.aantal := (L^.aantal + new^.aantal);
L^.naam := new^.naam;
L^.prijs := new^.prijs;
END;
L := L^.previous;
END;
NEW(L);
L := temp;
IF (new^.code # 0) & (~duplicate) THEN
IF L^.code # 0 THEN
L^.next := new;
L^.next^.previous := L;
L := L^.next;
ELSE
new^.next := NIL;
new^.previous := NIL;
L := new;
END;
END;
END;
END AddProduct;
PROCEDURE SortLijst*(VAR L: Lijst);
VAR
temp: Lijst;
sort: BOOLEAN;
counter, i: INTEGER;
BEGIN
IF (L # NIL) & (L^.previous # NIL) THEN (* We moeten enkel sorteren als er meer dan 1 element in de lijst zit *)
WHILE L^.previous # NIL DO (* Er wordt "teruggegaan" naar het tweede element (het eerste is al gesorteerd!) *)
L := L^.previous;
END;
L := L^.next;
(* Dit is het eigenlijke sorteerprocede *)
REPEAT
IF (L^.previous # NIL) & (L^.next # NIL) THEN
L := L^.next;
END;
counter := 0;
temp := L;
sort := FALSE;
WHILE (L^.previous # NIL) & (temp^.code < L^.previous^.code) DO
L := L^.previous;
INC(counter);
sort := TRUE;
END;
IF sort THEN
IF temp^.next = NIL THEN (* als het laatste element gesorteerd moet worden *)
temp^.previous^.next := NIL;
DEC(counter);
ELSE
temp^.previous^.next := temp^.next; (* de elementen waar Temp tussen stond worden aan elkaar gelinked *)
temp^.next^.previous := temp^.previous;
END;
temp^.next := L;
temp^.previous := L^.previous;
IF L^.previous # NIL THEN (* als het element wordt ingevoegd in de eerste positie *)
L^.previous^.next := temp;
END;
L^.previous := temp;
FOR i := 1 TO (counter - 1) DO (* we gaan terug naar de juiste plaats in de lijst om opnieuw te kunnen beginnen *)
L := L^.next;
END;
END;
UNTIL L^.next = NIL;
END;
END SortLijst;
PROCEDURE PrintLijst*(L: Lijst);
(*
Omschrijving : Print de huidige lijst.
Parameters : L: Lijst die geprint moet worden
Returntype : -
Algoritme : OO, dubbel gelinkte lijst
*)
VAR
i: INTEGER;
BEGIN
SortLijst(L);
IF (L = NIL) THEN
OutExt.Color(9);
OutExt.String("De lijst is leeg.");
OutExt.Ln();
OutExt.Color(15);
ELSE
OutExt.Color(9);
OutExt.String("CODE | PRODUCT | PRIJS | AANTAL");
OutExt.Ln();
OutExt.String("-----+-----------------------------------+---------+-------");
OutExt.Ln();
WHILE L^.previous # NIL DO
L := L^.previous;
END;
REPEAT
OutExt.Color(7);
OutExt.Int(L^.code, 4);
OutExt.Color(9);
OutExt.String(" | ");
OutExt.Color(7);
OutExt.String(L^.naam);
FOR i := 0 TO (32 - SHORT(Strings.Length(L^.naam))) DO
OutExt.String(" ");
END;
OutExt.Color(9);
OutExt.String(" |");
OutExt.Color(7);
OutExt.RealFix(L^.prijs, 8, 2);
OutExt.Color(9);
OutExt.String(" | ");
OutExt.Color(7);
OutExt.Int(L^.aantal, 6);
OutExt.Ln();
L := L^.next;
UNTIL (L = NIL);
OutExt.Color(15);
END;
END PrintLijst;
PROCEDURE Save*(L: Lijst);
VAR
bestand: Files.File;
bestandrider: Files.Rider;
BEGIN
IF L = NIL THEN
VerwijderBestand;
ELSE
WHILE L^.previous # NIL DO
L := L^.previous;
END;
bestand := Files.New("Kleinhandel.Dat");
Files.Set(bestandrider, bestand, 0);
REPEAT
Files.WriteInt(bestandrider, L^.code);
Files.WriteString(bestandrider, L^.naam);
Files.WriteReal(bestandrider, L^.prijs);
Files.WriteInt(bestandrider, L^.aantal);
L := L^.next;
UNTIL (L = NIL);
Files.Register(bestand);
OutExt.Color(7);
(* OutExt.String("Naar bestand weggeschreven."); *)
OutExt.Ln();
OutExt.Ln();
OutExt.Color(15);
END;
END Save;
PROCEDURE OpenFile*(VAR L: Lijst);
VAR
bestand: Files.File;
bestandrider: Files.Rider;
new: Lijst;
BEGIN
OutExt.Color(7);
(* OutExt.String("Bestand wordt ingelezen..."); *)
OutExt.Ln();
bestand := Files.Old("Kleinhandel.Dat");
IF (bestand = NIL) THEN
OutExt.Color(7);
OutExt.String("Bestand is niet gevonden.");
OutExt.Ln();
OutExt.Color(15);
L := NIL;
ELSE
Initialise(L);
Files.Set(bestandrider, bestand, 0);
WHILE (~bestandrider.eof) DO
NEW(new);
Files.ReadInt(bestandrider, new^.code);
Files.ReadString(bestandrider, new^.naam);
Files.ReadReal(bestandrider, new^.prijs);
Files.ReadInt(bestandrider, new^.aantal);
IF new^.code # 0 THEN
IF L^.code # 0 THEN
L^.next := new;
L^.next^.previous := L;
L := L^.next;
ELSE
new^.next := NIL;
new^.previous := NIL;
L := new;
END;
END;
END;
END;
END OpenFile;
PROCEDURE Delete*(VAR L: Lijst);
BEGIN
IF (L^.next = NIL) & (L^.previous = NIL) THEN
L := NIL;
ELSIF L^.next = NIL THEN
L := L^.previous;
L^.next := NIL;
ELSIF L^.previous = NIL THEN
L := L^.next;
L^.previous := NIL;
ELSE
L^.previous^.next := L^.next;
L^.next^.previous := L^.previous;
L := L^.next;
END;
END Delete;
PROCEDURE Quantity*(VAR L: Lijst);
VAR
code, quantity, totaantal: INTEGER;
totaal: REAL;
found: BOOLEAN;
rekening, new: Lijst;
BEGIN
OutExt.Color(9);
totaal := 0.0;
totaantal := 0;
In.Open();
In.Int(code);
In.Int(quantity);
Initialise(rekening);
WHILE (In.Done) & (L # NIL)DO
WHILE (L^.code # code) & (L^.previous # NIL) DO
L := L^.previous;
END;
IF L^.code = code THEN
found := TRUE;
ELSE
found := FALSE;
END;
IF ~found THEN
OutExt.String("Product nr. ");
OutExt.Int(code, 0);
OutExt.String(" is niet in stock.");
OutExt.Ln();
ELSIF quantity > L^.aantal THEN
OutExt.String("Er zijn slechts ");
OutExt.Int(L^.aantal, 0);
OutExt.String(" eenheden van product nr. ");
OutExt.Int(code, 0);
OutExt.String(" aanwezig! ");
OutExt.Ln();
ELSE
NEW(new);
new^.naam := L^.naam;
new^.code := L^.code;
new^.prijs := L^.prijs;
new^.aantal := quantity;
IF rekening^.code # 0 THEN
rekening^.next := new;
rekening^.next^.previous := rekening;
rekening := rekening^.next;
ELSE
new^.next := NIL;
new^.previous := NIL;
rekening := new;
END;
L^.aantal := (L^.aantal - quantity); (* Aantal veranderen in de lijst *)
totaal := (totaal + (L^.prijs * quantity)); (* subtotaal berekenen *)
totaantal := totaantal + quantity;
IF (L^.aantal = 0) THEN
Delete(L);
END;
END;
WHILE (L # NIL) & (L^.next # NIL) DO
L := L^.next;
END;
In.Int(code);
In.Int(quantity);
END;
OutExt.String("Rekening:");
OutExt.Ln();
PrintLijst(rekening);
OutExt.Color(9);
OutExt.String("-----+-----------------------------------+---------+-------");
OutExt.Ln();
OutExt.String("TOT | | ");
OutExt.RealFix(totaal, 7, 2);
OutExt.String(" | ");
OutExt.Int(totaantal, 6);
OutExt.Ln();
OutExt.Color(15);
Save(L);
END Quantity;
(* ======================= PROCEDURES VOOR DE GEBRUIKER ============================ *)
PROCEDURE Levering*;
VAR
A: Lijst;
BEGIN
OpenFile(A);
AddProduct(A);
PrintLijst(A);
Save(A);
END Levering;
PROCEDURE LeesBestand*;
VAR
A: Lijst;
BEGIN
OpenFile(A);
PrintLijst(A);
END LeesBestand;
PROCEDURE VerwijderBestand*;
VAR
succes: INTEGER;
BEGIN
Files.Delete("Kleinhandel.Dat", succes);
OutExt.Color(7);
IF succes = 0 THEN
OutExt.String("Bestand verwijderd.");
ELSE
OutExt.String("Bestand is niet gevonden.");
END;
OutExt.Ln();
OutExt.Color(15);
END VerwijderBestand;
PROCEDURE Verkoop*;
VAR
A: Lijst;
BEGIN
OpenFile(A);
Quantity(A);
PrintLijst(A);
Save(A);
END Verkoop;
BEGIN
OutExt.Open();
OutExt.Clear();
END Kleinhandel.
Tool:
Code: Select all
Builder.MarkErrors ^
Builder.ClearErrors ~
Builder.Compile \wsv2
OutExt.Mod
Kleinhandel.Mod
~
Builder.Compile \f2*
System.Free
Kleinhandel.Mod
OutExt.Mod
~
Kleinhandel.Levering
11 "Le Petit Prince" 13.99 7
37 "Solitudes - Forest Piano" 7.95 10
258 "Eureka 3D Puzzle" 3.50 12~
Kleinhandel.Levering
37 "Solitudes - Forest Piano" 6.95 25
129 "For Love of the Game" 9.95 20
258 "Eureka 3D Puzzle" 3.50 8
~
Kleinhandel.LeesBestand ~
Kleinhandel.VerwijderBestand ~
Kleinhandel.Verkoop
11 1
258 2
~
... en mijn output ziet er perfect uit zoals hij er uit moet zien
Code: Select all
CODE | PRODUCT | PRIJS | AANTAL
-----+-----------------------------------+---------+-------
11 | Le Petit Prince | 13.99 | 7
37 | Solitudes - Forest Piano | 7.95 | 10
258 | Eureka 3D Puzzle | 3.50 | 12
CODE | PRODUCT | PRIJS | AANTAL
-----+-----------------------------------+---------+-------
11 | Le Petit Prince | 13.99 | 7
37 | Solitudes - Forest Piano | 6.95 | 35
129 | For Love of the Game | 9.95 | 20
258 | Eureka 3D Puzzle | 3.50 | 20
Rekening:
CODE | PRODUCT | PRIJS | AANTAL
-----+-----------------------------------+---------+-------
11 | Le Petit Prince | 13.99 | 1
258 | Eureka 3D Puzzle | 3.50 | 2
-----+-----------------------------------+---------+-------
TOT | | 20.99 | 3
CODE | PRODUCT | PRIJS | AANTAL
-----+-----------------------------------+---------+-------
11 | Le Petit Prince | 13.99 | 6
37 | Solitudes - Forest Piano | 6.95 | 35
129 | For Love of the Game | 9.95 | 20
258 | Eureka 3D Puzzle | 3.50 | 18
EDIT: er zat een foutje in de Sort procedure: hij gaf een Trap als de lijst NIL was
EDIT2: nog wat foutjes verbeterd met lege lijsten

Posted: Fri Dec 23, 2005 5:38 pm
by Norfolk
mijn printlijst werkt toch met OO...