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 :shock: :shock:

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
dien ftp
ftp://beatle.dynu.com:2001/1ste%20Bache ... Practicum/

login s0051331
pass ftpunief

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 :D.

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 8), met module Input (zie Watson.ShowDef Input~ :wink:).
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 8), met module Input (zie Watson.ShowDef Input~ :wink:).
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 :D.
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 :wink:.

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 :roll:

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