Program in pascal [duplicate] - pascal

This question already has answers here:
What is that the Error of Illegal assignment and how to correct it?
(2 answers)
Closed last month.
Just started to learn the Pascal programming language, I wrote an assignment that was given at the university, here is my assignment:
Build a program that will perform the following actions:
retrieve data of N elements (brand, name, atomic weight, density)
find the average density value
finding the three elements with the lowest atomic mass
writing the inputs and outputs to the text file "elements.txt"
wrote code for it, in theory everything should work, but it gives out some strange errors, if I have standard errors, I apologize for them.
program MINERALY_;
uses Crt;
const NMAX=200;
type MINERAL=record
NAZOV:string;
HUST:real;
ATOM:real;
ZNACKA:real;
end;
MINERALY=array[1..NMAX] of MINERAL;
var N,i,C,D:integer;
V:real;
MI:MINERALY;
S:string;
SUB:text;
PTVRD,CTVRD:real;
MINATOM:real;
begin
ClrScr;
Writeln('Program pre nacitanie mineralov a vypocet hodnot ich jednotlivych
vlastnosti.');
Writeln('===============================================================================');
{Vynulovanie hodnot}
CTVRD:=0;
PTVRD:=0;
MINATOM:=0;
{Nacitanie poctu mineralov}
Writeln;
Write('Zadajte pocet nacitavanych mineralov (Maximalne 200): ');
repeat
Readln(S);
Val(S,D,C);
if (C<>0) or (D<=0) or (D>200) then
begin
Writeln;
Writeln('Zadali ste nespravny pocet, alebo ste zadali nespravne znaky !');
Writeln('Hodnota moze byt od 1-200');
Write('Zadajte pocet mineralov este raz: ');
end;
N:=D;
until(N>0) and (N<=200) and (C=0);
{nacitavanie udajov, zistovanie max. a min. hodnot atd.}
for i:=1 to N do
begin
Writeln;
Write('Zadajte Znacku: ');
Readln(MI[i].ZNACKA);
Writeln;
Write('Zadajte nazov: ');
Readln(MI[i].NAZOV);
Write('Zadajte hustotu (musi byt vacsia ako 0): ');
repeat
Readln(S);
Val(S,V,C);
if (C<>0) or (V<0) then
begin
Writeln;
Writeln('Zadali ste nespravnu hodnotu, alebo ste zadali nespravne znaky !');
Write('Zadajte hustotu este raz (musi byt vacsia ako 0): ');
end;
until (V>0) and (C=0);
MI[i].HUST:=V;
CTVRD:=CTVRD+MI[i].HUST;
Write('Zadajte atómovou hmotnosťou (musi byt vacsia ako 0): ');
repeat
Readln(S);
Val(S,V,C);
if (C<>0) or (V<0) then
begin
Writeln;
Writeln('Zadali ste nespravnu hodnotu, alebo ste zadali nespravne znaky !');
Write('Zadajte atómovou hmotnosťou este raz (musi byt vascia ako 0): ');
end;
until (V>0) and (C=0);
MI[i].ATOM:=V;
if (i=1) then MINATOM:=MI[i].ATOM;
if (MI[i].ATOM<MINATOM) then MINATOM:=MI[i].ATOM;
PTVRD:=CTVRD/N;
Writeln;
Writeln('Vypocitane hodnoty: ');
Writeln('===================================');
Writeln;
Writeln('Priemerna tvrdost mineralov: ',PTVRD:2:2);
Writeln('Najnizsia hustota: ',MINATOM:2:2);
Assign(SUB,'mineral.txt');
Rewrite(SUB);
Writeln(SUB,'Nacitane mineraly: ');
Writeln(SUB,'===================================');
Writeln(SUB,'');
for i:=1 to N do
begin
Writeln(SUB,i,'. mineral: ');
Writeln(SUB,'Nazov: ',MI[i].NAZOV);
Writeln(SUB,'Znacka: ',MI[i].ZNACKA);
Writeln(SUB,'Tvrdost: ',MI[i].HUST:2:2);
Writeln(SUB,'Hustota: ',MI[i].ATOM:2:2);
Writeln(SUB,'');
end;
Writeln(SUB,'===================================');
Writeln(SUB,'Vypocitane hodnoty: ');
Writeln(SUB,'===================================');
Writeln(SUB,'');
Writeln(SUB,'Priemerna tvrdost mineralov: ',PTVRD:2:2);
Writeln(SUB,'Najnizsia hustota: ',MINATOM:2:2);
Close(SUB);
Writeln;
Writeln;
Writeln('Pre ukoncenie programu stlacte ENTER !');
Readln;
end.
Here are the errors this code gives me:
Compiling main.pas
main.pas(109,14) Error: Illegal assignment to for-loop variable "i"
main.pas(132,4) Fatal: Syntax error, ";" expected but "." found
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode

Error: Illegal assignment to for-loop variable "i"
is when you are trying to change the value of i while the loop is still working.
since you didn't end; the loop you canno't change the value of i you can use another variable, j for example, unless your first for-loop is over and you forgot the end; key

Related

How to find out Error No. in ObjFPC in a try-except statement

I am trying to find a way to detect the error no in objfpc, what I tried is shown below:
Program ErrorHandling;
{$R+}
{$MODE objfpc}
Uses
SysUtils, crt;
Var
intvar: 1 .. 100;
Begin
Try
clrscr;
writeln( 'enter intvar: ');
readln(intvar);
Except
on
e: Exception
Do
Begin
writeln('In Exception, IOResult: ',IOResult);
Case IOResult Of
201: writeln('Range intvar out of range 1-100!'); {How can we find that Error no is 201}
Else
writeln('Unkown Error!'); readln;
End
End
End;
writeln('intvar: ' , intvar);
readln;
End.
But How can we find if the 201 Range Error occurs. I tried using IOResult command but it always shows "Unknown Error" string of my case statement.
Using exceptions you can check error type by type of exception itself.
The classic way is:
try
clrscr;
writeln('enter intvar: ');
readln(intvar);
except
on e: ERangeError do // Executes when raised exception is ERangeError
begin
Writeln('Range intvar out of range 1-100!');
end;
on e: Exception do // Executes for any other exceptions
begin
Writeln(e.ClassName); // Shows exception class you can use at the "on e:" constuction
Writeln(e.Message);
end;
end;
Look at The try...except statement in the official documentation.

Convert if statement to case of in pascal?

Im using pascal, can u convert this code statement to case of ? In pascal ?
This my program on pascal, if statement to case of.
Thankyou very much
TYPE
MHS = record
nama1,nama2:string;
ipk1,ipk2:longint;
nim1,nim2:integer;
end;
var
DataMhs : MHS;
Begin
clrscr;
write('Masukan Nama Mahasiswa 1 : ');
readln(DataMhs.nama1);
write('Masukan NIM Mahasiswa 1 : ');
readln(DataMhs.nim1);
write('Masukan IPK Mahasiswa 1 : ');
readln(DataMhs.ipk1);
write('Masukan Nama Mahasiswa 2 : ');
readln(DataMhs.nama2);
write('Masukan NIM Mahasiswa 2 : ');
readln(DataMhs.nim2);
write('Masukan IPK Mahasiswa 2 : ');
readln(DataMhs.ipk2);
if DataMhs.ipk1 > DataMhs.ipk2 then
write('IPK ',DataMhs.nama1,'Lebih besar')
else if DataMhs.ipk2 > DataMhs.ipk1 then
write('IPK ',DataMhs.nama2,'Lebih besar')
else
write('IPK ',DataMhs.nama1,' dengan ',DataMhs.ipk2,' SAMA');
readln;
end.
I dont know how to convert it, please help. Haha
If you want to make you code better looking, then you can use that -->
with DataMhs do
begin
if ipk1 > ipk2 then write('IPK ',DataMhs.nama1,'Lebih besar');
else if ipk1 < ipk2 then write('IPK ',DataMhs.nama2,'Lebih besar');
else write('IPK ',DataMhs.nama1,' dengan ',DataMhs.ipk2,' SAMA');
end;
But I do not think that the case
is useful for that. Because case is used for known values such as:
case a of
1: Writeln(' Some code here') ;
2: Writeln(' Some code here') ;
3: Writeln(' Some code here') ;
4: Writeln(' Some code here') ;
else Writeln(' That is used for other values. ');
end;
Case cannot be used for that kind of problem.
I suspect that what you have in mind might be something like the following:
type
TCompareResult = (cmpLeftGreater, cmpRightGreater, cmpEqual);
case CompareInts(DataMhs.ipk1, DataMhs.ipk2) of
cmpLeftGreater:
write('IPK ', DataMhs.nama1, 'Lebih besar');
cmpRightGreater:
write('IPK ', DataMhs.nama2, 'Lebih besar');
else {cmpEqual}
write('IPK ', DataMhs.nama1, ' dengan ', DataMhs.ipk2, ' SAMA');
end;
However, you still need to implement this CompareInts function, and it will still need to use the same conditional structure you already have in your original code:
function CompareInts(left, right: Integer): TCompareResult;
begin
if left > right then
Result := cmpLeftGreater
else if right > left then
Result := cmpRightGreater
else
Result := cmpEqual;
end;
Thus, the function doesn't really gain you much.

How to display time in Real-time in Virtual Pascal

I've been making a stock-keeping program for my school (In Virtual Pascal) and as part of that, I want to be able to display today's date along with the current time at the main menu of the program. Now, I've been able to display the correct date as that was pretty simple.
But when I use this code for displaying Time, it only displays the time at which the program is compiled, and does not refresh to display the current time.
Procedure getTheTime;
VAR
Hour, Minute, Second, Sec100 : WORD;
BEGIN
GetTime( Hour, Minute, Second, Sec100 );
TEXTCOLOR(lightgreen);
whereY;
whereX;
WRITE;WRITE(' ');
WRITE( Hour, ':', Minute, ':', Second, '.', Sec100);
END;
Basically, it displays this: 19:8:41.75
And I want the time to refresh as time goes by.
Any help would be appreciated.
The procedure where I call the getTheTime procedure.
Procedure mainMenu;
BEGIN
REPEAT
CLRSCR;
getTheDate;
getTheTime;
TEXTCOLOR(15);
GOTOXY(18,2);
WRITELN('Welcome To RAK Academy''s School Shop');
TEXTCOLOR(11);
GOTOXY(18,3);
WRITELN('------------------------------------');
WRITELN;
WRITE('A ':25);
TEXTCOLOR(15);
WRITELN(': Customers');
WRITELN;
TEXTCOLOR(11);
WRITE('B ':25);
TEXTCOLOR(15);
WRITELN(': Products');
WRITELN;
TEXTCOLOR(11);
WRITE('C ':25);
TEXTCOLOR(15);
WRITELN(': Orders');
WRITELN;
TEXTCOLOR(11);
WRITE('X ':25);
TEXTCOLOR(15);
WRITELN(': Exit');
WRITELN;
GOTOXY(0,3);
WRITE('Enter Choice: ':23);
MenuChoice:=UPCASE(READKEY);
sndPlaySound('F:\School\IB 1\HL subjects\Computer Science\Pascal programs\InternalAssessment\sound files\beep.wav', snd_Async or snd_NoDefault );
TEXTCOLOR(11);;
WRITELN(MenuChoice);
TEXTCOLOR(15);
DELAY(200);
CASE MenuChoice OF
'A' : CustomersMenu;
'B' : ProductsMenu;
'C' : OrdersMenu;
'X' : BEGIN
sndPlaySound('F:\School\IB 1\HL subjects\Computer Science\Pascal programs\InternalAssessment\sound files\end.wav', snd_Async or snd_NoDefault );
WRITELN;
WRITELN('Program Is Shutting Down');
GOTOXY(25,15);
DELAY(750);
WRITE('.');
DELAY(750);
WRITE('.');
DELAY(750);
WRITE('.');
DELAY(750);
END
ELSE
BEGIN
WRITELN;
TEXTCOLOR(12);
WRITELN('ERROR - Only Enter A-B Or X To Exit. Please Try Again.');
TEXTCOLOR(11);
READKEY;
END;
END;
UNTIL menuChoice='X';
END;
It is not the time at which the program is compiled, but the time at which the program is run.
The code between BEGIN-END runs once and then updates the time.
If you want the time to update you need to add a timer that updates the time when the OnTimer event triggers.
From memory, to give you an idea how to do this:
var updatecounter : integer;
mustexit : Boolean;
updatecounter:=10; mustexit:=false;
repeat //eventloop start.
if keypressed then
begin
c:=readkey;
if c=#0 then
c2:=readkey; // C=#0 is functionkey, read second value
mustexit:=processkey(c,c2); // process whatever key is pressed
end
else
begin
sleep(10); // windows/winprocs unit? Don't know VP that well.
// pauses 10ms
dec(updatecounter);
if updatecounter=0 then // every 10*10ms update time
begin
updatetime; // update the time.
updatecounter:=10;
end;
end;
until mustexit;
You can implement the various procedures and play with constants to get the responsivenes you want.

how to get a variable out of a procedure in the right way in PASCAL?

I'm following an internet course on the basics of programming. After making a diagram I convert it to code, right now this is PASCAL language.
I'm having a problem with procedures and can't find an answer, nor in the course, nor with some google-ing.
I want to get a variavble back form a procedure. Right now iIhave a working piece of code but I think this is not the good way of working. Here's an extract of the code:
program WELKEWAGEN;
// declare your variables here
var T, N, KM, vari, prijsDW, prijsBW, jrenGEBR, taksDW, taksBW, prijsB, verbrBW, prijsD, verbrDW : real;
procedure OPHALEN(para : string);
begin
repeat
writeln('geef de ', para , ' op');
readln(vari);
until (vari > 0);
end;
begin
//this is the main program but there is more code ofcourse
OPHALEN('prijs benzinewagen');
prijsBW := vari;
//...
end.
Now the internet course says I should program it like this:
begin
//...
prijsBW := OPHALEN('prijs benzinewagen');
//...
end.
But this is not working.
I get following errors:
WELKEWAGEN.pas(24,14) Error: Incompatible types: got "untyped" expected "Real"
WELKEWAGEN.pas(50) Fatal: There were 1 errors compiling module, stopping
pas(24,14) is this line: prijsBW := OPHALEN('prijs benzinewagen');
Procedures don't return values, so the syntax
prijsBW := OPHALEN('prijs benzinewagen');
is invalid.
If you want to return a value, you need to define a function instead:
function OPHALEN(para : string): Real;
var
Res: Real;
begin
Res := 0;
repeat
writeln('geef de ', para , ' op');
readln(Res);
until (Res > 0);
OPHALEN := Res;
end;
Note that the (bad) global variables you're using mean you don't have to return anything at all, because a procedure can access and change that global variable directly (but you have no way of knowing when the procedure is finished):
procedure OPHALEN(para : string);
begin
vari := 0;
repeat
writeln('geef de ', para , ' op');
readln(vari);
until (vari > 0);
end;
Modern Pascal dialects (such as Delphi and FreePascal) allow a cleaner syntax for the return value of functions by using an automatically declared function result variable of the proper type for you, named Result (because that's what it is - the result of the function):
function OPHALEN(para : string): Real;
begin
Result := 0;
repeat
writeln('geef de ', para , ' op');
readln(Result);
until (Result > 0);
end;
If you need to return multiple values, you can use var parameters, which allow them to be changed inside the function.
procedure OPHALEN(para: string; var RetVal: Real);
begin
RetVal := 0;
repeat
writeln('geef de ', para , ' op');
readln(RetVal);
until (RetVal > 0);
end;
Your original code (and the examples I've provided above) all fail to allow the user to cancel, BTW. There should be some way to exit the loop for the user; otherwise, your code just endlessly loops, writing para to the screen and then waiting for input. This has a tendency to annoy users.

Pascal comparison error

I have a problem with my very simple Pascal code. (I just started to learn Pascal.)
So it's about an age comparison code then rest can be seen through the code.
program Test;
uses crt;
var
age : real;
Begin
writeln('Enter your age: ');
readln(age);
if age>18 then
if age<100 then
Begin
clrscr;
textcolor(lightgreen);
writeln('Access Granted');
end
else
if age<18 then
Begin
clrscr;
textcolor(lightred);
writeln('ACCESS DENIED');
writeln('Reason:You are way to young');
end
else
Begin
clrscr;
textcolor(lightred);
writeln('ACCESS DENIED');
writeln('Reason:You are way to old');
end;
readln;
end.
When I enter a value below 18 as the age, I expect the program to respond:
ACCESS DENIED
Reason:You are way to young
but I don't get any output. Why?
Sometimes text indentation helps you to see the issue. Here's your code with indentation added:
program Test;
uses crt;
var
age : real;
Begin
writeln('Enter your age: ');
readln(age);
if age>18 then
if age<100 then
Begin
clrscr;
textcolor(lightgreen);
writeln('Access Granted');
end
else
if age<18 then
Begin
clrscr;
textcolor(lightred);
writeln('ACCESS DENIED');
writeln('Reason:You are way to young');
end
else
Begin
clrscr;
textcolor(lightred);
writeln('ACCESS DENIED');
writeln('Reason:You are way to old');
end;
readln;
end.
And to make the implemented logic more obvious, I will now represent the nested ifs without the code that they execute:
if age>18 then
if age<100 then
... // Access Granted
else
if age<18 then
... // You are way too young
else
... // You are way too old
;
It is easy to see now that the branch marked as You are way too young is never reached. It is supposed to be executed when age is less than 18, but that if statement is nested into another if which will call it only when age is greater than 18. So, age should first qualify as greater than 18, then less than 18 in order for that branch to execute – you can see now why you do not get the expected result!
The intended logic could possibly be implemented this way:
if age>18 then
if age<100 then
... // Access Granted
else // i.e. "if age >= 100"
... // You are way too old
else // now this "else" belongs to the first "if"
... // You are way too young
;
I believe you should be able to fill in the missing code blocks correctly.
Just one last note: you might want to change age>18 to age>=18, so that 18 proper does not qualify as "too young".

Resources