why am i getting 22 / 3 itprog~1.pas Fatal: Syntax error, ; expected but ELSE found - pascal

PROGRAM approvedapplicants(input,output);
uses crt;
var
applcntname,housingcomm,clarendon_court,providence_gardens,
sangre_grande_villas:string;
slry,spcslry:integer;
c_qual_sal,s_qual_sal,p_qual_sal,qualifying_salary:integer;
BEGIN
writeln('enter applicant name, salary, spouce salary');
readln(applcntname,slry,spcslry);
writeln('enter housing community');
readln(housingcomm);
BEGIN
qualifying_salary:=0;
IF(housingcomm=clarendon_court)
then
qualifying_salary:=$12500;
writeln('you have selected clarendon court!');
readln(c_qual_sal) ;
end if ;
else if(housingcomm=sangre_grande_villas)then
qualifying_salary:=$9500;
writeln('you have selected sangre grande villas!');
readln(s_qual_sal);
end if ;
else(housingcomm=providence_gardens)then;
qualifying_salary:=$7500;
writeln('you have selected providence gardens!');
readln(p_qual_sal);
end if;
END.

Ordinarily, on SO, we don't post answers to homework/coursework, but your code is so far wide of the mark that I think it's ok to make an exception in this case.
Try compiling and running this program, which I think does pretty much what I think you are intending, then I'll explain a few things about it:
program approvedapplicants(input,output);
uses crt;
var
ApplicantName,
HousingCommunity,
ClarendonCourt,
ProvidenceGardens,
SangreGrandVillas :string;
Salary,
SpouseSalary,
QualifyingSalary : Integer;
CQualSal,
PQualSal,
SQualSal : Integer;
slry,spcslry:integer;
begin
ClarendonCourt := 'Clarendon Court';
ProvidenceGardens := 'Providence Gardens';
SangreGrandVillas := 'Sangre Grand Villas';
QualifyingSalary := 0;
writeln('enter applicant name');
readln(ApplicantName);
writeln('enter salary');
readln(Salary);
writeln('enter spouse salary');
readln(SpouseSalary);
writeln('enter housing community');
readln(HousingCommunity);
if (HousingCommunity = ClarendonCourt) then begin
QualifyingSalary := $12500;
writeln('you have selected clarendon court!');
readln(CQualSal);
end
else
if(HousingCommunity = SangreGrandVillas)then begin
QualifyingSalary := $9500;
writeln('you have selected sangre grande villas!');
readln(SQualSal);
end
else
if HousingCommunity = ProvidenceGardens then begin
QualifyingSalary :=$7500;
writeln('you have selected providence gardens!');
readln(CQualSal);
end;
end.
Firstly, notice how much easier it is to read and follow its logic. This is mainly
because of
The use of a layout (including indented blocks) which reflects the logical
structure of the code.
The use of consistent, lower case for keywords like program, begin, end, etc.
Keywords are usually the least interesting contents of source code, and it is distracting
to have them SHOUTing at you.
The avoidance of arbitrarily dropping characters from variable names (like the "i"
and second "a" of "applicant". In the days of interpreted code running on slow machines there was
argubably some justification for this, but not any more imo. Likewise, the avoidance
of underscores in variable names - admittedly this is more of a personal preference, but
why have you used them everywhere except the applicant's name?
Secondly, you still have quite a bit of work to do.
Having 3 different variables for the salary (?) numbers you prompt the user
for, one for each of the 3 communities, is probably a bad idea unless you will
subsequently want to work with all 3 figures at the same time. Also, you haven't provided text prompts to tell the user what information to enter for the readln(c_qual_sal) etc statements. It wasn't obvious to me what you intend, so I have not tried to guess.
The way you echo the user's choice of community is just creating you a maintenance
headache (what if you want to add more communities later?). It would be better
to have a variable which you set to whichever of the community names matches
what the user has entered.
You have 3 statements to execute for each community, which are duplicated for
each community. The only one you actually need is the QualifyingSalary one -
the others can execute regardless of the inputted community.

Related

Fatal: Syntax error, ; expected but identifier TUNJANGAN found [duplicate]

It has been around 20 years since I last had to write in Pascal. I can't seem to use the structure elements of the language correctly where I am nesting if then blocks using begin and end. For example this gets me an Compiler Error "Identifier Expected".
procedure InitializeWizard;
begin
Log('Initialize Wizard');
if IsAdminLoggedOn then begin
SetupUserGroup();
SomeOtherProcedure();
else begin (*Identifier Expected*)
Log('User is not an administrator.');
msgbox('The current user is not administrator.', mbInformation, MB_OK);
end
end;
end;
Of course if I remove the if then block and the begin end blocks associated with them then everything is OK.
Sometimes I get it this kind of syntax right and it works out OK, but the problems become exasperated when nesting the if then else blocks.
Solving the problem is not enough here. I want to have a better understanding how to use these blocks. I am clearly missing a concept. Something from C++ or C# is probably creeping in from another part of my mind and messing up my understanding. I have read a few articles about it, and well I think I understand it and then I don't.
You have to match every begin with an end at the same level, like
if Condition then
begin
DoSomething;
end
else
begin
DoADifferentThing;
end;
You can shorten the number of lines used without affecting the placement, if you prefer. (The above might be easier when you're first getting used to the syntax, though.)
if Condition then begin
DoSomething
end else begin
DoADifferentThing;
end;
If you're executing a single statement, the begin..end are optional. Note that the first condition does not contain a terminating ;, as you're not yet ending the statement:
if Condition then
DoSomething
else
DoADifferentThing;
The semicolon is optional at the last statement in a block (although I typically include it even when it's optional, to avoid future issues when you add a line and forget to update the preceding line at the same time).
if Condition then
begin
DoSomething; // Semicolon required here
DoSomethingElse; // Semicolon optional here
end; // Semicolon required here unless the
// next line is another 'end'.
You can combine single and multiple statement blocks as well:
if Condition then
begin
DoSomething;
DoSomethingElse;
end
else
DoADifferentThing;
if Condition then
DoSomething
else
begin
DoADifferentThing;
DoAnotherDifferentThing;
end;
The correct use for your code would be:
procedure InitializeWizard;
begin
Log('Initialize Wizard');
if IsAdminLoggedOn then
begin
SetupUserGroup();
SomeOtherProcedure();
end
else
begin
Log('User is not an administrator.');
msgbox('The current user is not administrator.', mbInformation, MB_OK);
end;
end;

Why does syntax error appear after running code?

presently learning how to code in pascal and vba. Assisting my daughter who is preparing for examinations next year. I am stuck on a problem concerning her present assignment. After running the code the following errors were received:
main.pas(1,2) Fatal: Syntax error, "BEGIN" expected but "identifier N" found
Fatal: Compilation aborted
Tried fixing the code, but as i said I have just started learning to code.
n: integer; (*n is ID number for each candidate*)
DV: integer; (*DV is the number of district votes available*)
VR: integer; (*VR is the number of votes received by the candidate in
the district*)
x: integer;
y: integer;
Divide: integer;
found: Boolean;
n: array[1..10] of integer; (*n is an array of 10 integers*)
Names: array[1…10] of string = (‘Richards’, ‘Gumbs’, ‘Carty’,
‘Fleming’, ‘Jones’, ‘Amorowat’, ‘De la cruz’, ‘Walker’,
‘Brooks’, ‘Baker’);
DV: array[1…10] of integer = (‘200’, ‘900’, ‘700’, ‘100’, ‘80’, ‘15’,
‘6, ‘20’, ‘50’, ‘1’);
VR: array[1…10] of integer = (‘50’, ‘700’, ‘600’, ‘20’, ‘30’, ‘2’,
‘6, ‘3’, ‘30’, ‘2’);
For x := 1 to 10 do
Begin
Repeat
Found:=false;
writeln('Enter Candidate ID Number: ’);
readln(n);
For y:= 1 to 10 do
if n = n[y] then
Found = true;
writeln(‘Name of Candidate is’ Names: array[1] ‘.’);
readln;
writeln(‘Number of votes available in the District is’
DV: array[1] ‘.’);
readln;
writeln(‘Number of votes received by the Candidate in the
District is’ VR: array[1] ‘.’);
readln;
Endif;
For y:= 1 to 10 do
if n = n[y] then
Divide:= (DV: array[1] DIV VR: array[1]);
Result:= Divide;
writeln(‘The percentage of votes received by’ Names:
array[1] ‘is’ Result ‘.’);
readln;
if Result:>= 0.20 then
writeln(‘The candidate,’ Names: array[1] ‘is to receive a
refund.’);
readln;
Elseif
writeln(‘The candidate,’ Names: array[1] ‘will not receive
a refund.’);
readln;
Endif;
Endif;
End;
The expected result is to choose a candidate by his ID number which would lead to his name, the number of vote available in a district and the number of votes the candidate obtained being displayed. it would then result in a calculation between the two vote counts (division) and if the percentage is greater than 20% he would receive a refund, if less than 20% he would not receive a refund. either result should be displayed.
I'm afraid that you q, as it currently stands, isn't really suited to SO
because SO is really about specific (single) programming problems, not
incrementally debugging source code (see Sertac's comment), nor providing
online tutorials, which I think you probably need at this point. And I feel
rather uncomfortable about posting this as an answer, because it isn't one
in the normal SO sense. However it seems to me that you could use a few pointers:
Unless you absolutely have to use the online compiler, download
and use a free online one like Free Pascal, which is well supported, uses
standard Pascal syntax, and I'm sure there are basic first-time tutorials
available. See here to download Lazarus, which is an excellent IDE for Free Pascal (which is included
in the install) and here for an introductory tutorial.
Secondly, there are structural and syntactic elements of your source-code
which are definitely not standard Pascal, in particular endif and elseif.
Another example is that in standard Pascal, you have to surround a string (like your
Richards, etc) with single-quotes ', not precede the string by a back-quote. This is very possibly the cause of your "illegal character" error
For a decent Free Pascal introductory
tutorial see here and this youtube tutorial, both found by googling
"free pascal" introductory tutorial.
Fourthly, your online compiler ought to be complaining about the endif abd elseifs, the incorrectly string formatting and the fact that several of your variables are duplicated (DV and VR used as the names of an integer variable and an array, for example as in Pascal, identifiers within the same 'scope' need to have unique names (the fact that I should explain what 'scope' means is a sign that what the q needs is a tutorial).

Find & Extract hashtags in text

I'm looking for an easy/quick way to identify and extract hashtags from a string, and temporarily store them separately - e.g.:
If I have the following string:
2017-08-31 This is a useless sentence being used as an example. #Example #Date:2017-09-01 #NothingWow (and then some more text for good measure).
Then I want to be able to get this:
#Example
#Date:2017-09-01
#NothingWow
I figured storing it in a TStringList should be sufficient until I'm done. I just need to store them outside of the original string for easier cross referencing, then if the original string changes, add them back at the end.
(but that's easy - its the extracting part I'm having trouble with)
It should start at the # and end/break when it encounters a [space].
The way I initially planned it was to use Boolean flags (defaulted to False), then check for the different hashtags, set them to true if found, and extract anything after a [:] separately.
(but I'm sure there is a better way of doing it)
Any advice will be greatly appreciated.
The following shows a simple console application which you could use as the basis
for a solution. It works because assigning your input string to the DelimitedText property of a StringList causes the StringList to parse the input into a series of space-limited lines. It is then a simple matter to look for the ones which start with a #.
The code is written as a Delphi console application but should be trivial to convert to Lazarus/FPC.
Code:
program HashTags;
{$APPTYPE CONSOLE}
uses
Classes, SysUtils;
procedure TestHashTags;
var
TL : TStringList;
S : String;
i : Integer;
begin
TL := TStringList.Create;
try
S := '2017-08-31 This is a useless sentence being used as an example. #Example #Date:2017-09-01 #NothingWow (and then some more text for good measure)';
TL.DelimitedText := S;
for i := 0 to TL.Count - 1 do begin
if Pos('#', TL[i]) = 1 then
writeln(i, ' ', TL[i]);
end;
finally
TL.Free;
end;
readln;
end;
begin
TestHashTags;
end.

Weird runtime error while implementing a bubble sort in Pascal

This snippet not only causes a runtime error, it makes FPC close if I run it using the debugger.
procedure sortplayersbyscore(var vAux:tplayers);
procedure swap(var a:trplayers;var b:trplayers);
var
rAux:trplayers;
begin
rAux:=a;
a:=b;
b:=rAux;
end;
var
i,j:integer;
sorted:boolean;
begin
vAux:=playersarray;
i:=1;
sorted:=false;
while (i <= MAXPLAYERS -1) and not sorted do
begin
j:=1;
sorted:=true;
while (j <= MAXPLAYERS -i) do
begin
if (vAux[j].score < vAux[j+1].score) then
begin
swap(vAux[j],vAux[j+1]);
sorted:=false;
end;
inc(j);
end;
inc(i);
end;
end;
The code itself is part of a really big source file, I can post the whole thing but the responsible for the error is just that bunch of lines. The debugger terminates at line:
swap(vAux[j],vAux[j+1]);
tplayers is just a type defined as an array of records that contain score (an integer) among a bunch of other variables. trplayers is the type of the aforementioned records. I'm at a total loss; FPC (while not under debugging mode) spits an out-of-range error but under my watches I see that the variables I'm trying to read exist. Any help is really appreciated!
rAux:trplayers; have you typed a wrong symbol or the type here really contains "r" in its name?
It looks valid (other than typos) ... so let's try something simple.
What's the value of "j" when you abort?
If the debugger won't tell you, try adding:
writeln ('j = ', j);
just before the "swap" call.
As Yochai's question implied, your array needs to be dimensioned at least from
1 (or lower) to MAXPLAYERS (or larger). (I.e.: 0..MAXPLAYERS-1 would not work,
but 1..MAXPLAYERS should.)

Pascal programming help

I posted this earlier and it got closed because I did not show my try at coding it, so here is the question:
SECTIONS
$160 = section 1
$220 = section 2
$280 = section 3
$350 = section 4
$425 = section 5
Develop pseudocode that accepts as input the name of an unspecified number of masqueraders who each have paid the full cost of their costume and the amount each has paid.
A masquerader may have paid for a costume in any of the five sections in the band. The algorithm should determine the section in which the masquerader plays, based on the amount he/she has paid for the costume. The algorithm should also determine the number of masqueraders who have paid for costumes in each section.
The names of persons and the section for which they have paid should be printed. A listing of the sections and the total number of persons registered to play in each section should also be printed, along with the total amount paid in each section.
Here is my try at it: *Note this is programmed in Pascal, and I need help fixing it up and finishing it. Please help and thanks again.
program Masqueraders;
uses
WinCrt; { Allows Writeln, Readln, cursor movement, etc. }
const
MAX = 5; {this determine the amount of masquarader entered}
Type
listname = Array[1..MAX] of string;
listsect = Array[1..MAX] of string;
var
names : listname;
sections : listsect;
i, amount, TotalMas, TotalAmt, c1, c2, c3, c4, c5, amt1, amt2, amt3, amt4, amt5 : integer;
begin
amount := 1;
while amount <> 0 do
begin
i := i + 1;
readln(names[i]);
readln(amount);
if(amount = 160) then
begin
c1 := c1 + 1; {Count the number of persons for section 1}
amt1 := amt1 + amount; {accumulate the amount for section 1}
sections[i] := 'Section 1';
end;
if(amount = 220) then
begin
c2 := c2 + 1; {Count the number of persons for section 1}
amt2 := amt2 + amount; {accumulate the amount for section 1}
sections[i] := 'Section 2';
end; {end the IF for section 2}
if(amount = 280) then
begin
c3 := c3 + 1; {Count the number of persons for section 1}
amt3 := amt3 + amount; {accumulate the amount for section 1}
sections[i] := 'Section 3';
end; {end the IF for section 3}
if(amount = 350) then
begin
c4 := c4 + 1;
amt4 := amt4 + amount;
sections[i] := 'Section4';
end; {end If for section 4}
if (amount = 425) then
begin
c5 := c5 + 1;
amt5 := amt5 + amount;
sections[i] := 'Section5';
end;{end the while loop}
TotalMas := c1 + c2 + c3;
TotalAmt := amt1 + amt2 + amt3;
writeln('Name Section'); {Heading for the output}
for i := 1 to MAX do
begin
write(names[i]);
writeln(' ',sections[i]);
end;
writeln('Section 1: ');
write('Masquader: ', c1);
write('Amount: ', amt1);
writeln('Total Number of Masquarader: ', TotalMas);
writeln('Total Amount Paid by masquarader: ', TotalAmt);
end;
end.
In short, it should accept an undefined number of people and assign them to their respective sections based on the amount of money they entered, then calculate the number of people in each section. This is my current output:
Name John Money=160 Section 1
Name Keith Money=220 Section John
This is what I want:
Name John Money=160 Section1
Name Keith Money=220 Section2
I'm not really familiar with Pascal so I can't tell you how to fix this but one issue I notice is that your code seems to violate the "DRY" rule: Don't Repeat Yourself. The code inside each if amt = xxx block looks almost exactly the same, so is there a way you can write that code once, and then call your code with different parameters each time? Something so that you're not rewriting the same code five times.
Here's are a few hints to improve your code:
Do you think there might be a way to print "Section {i}" in your final loop without looking it up using sections[i], thereby negating the need for the array completely?
How could you build this so that adding a section 6 wouldn't require modifications to your code?
listname and listsect are awfully similar, what modifications to your code could you do to eliminate the need to have two identical definitions?
What happens if the user enters 0 for the amount the third time they are prompted?
Note: one of these hints should point you directly to the source of your problem.
Here are the problems I see:
The requirements say an "unspecified number of masqueraders" but you have set the max to 5. You can't store the list of names in a fixed size array if there are possibly going to be more than 5 masqueraders. As is, the app may either crash or corrupt memory (depending on the version of Pascal you're using) when user enters the 6th masquerader. If you are allowed to print the masquerader's Name and Section immediately after it is input, then you should print that right after the user inputs the Name and Amount (not after the input while loop). However, if it is required that you print the list of Names and Sections after all input, then you need to store the Name+Section in a variable length data structure like a linked list or even simpler a string.
The variables c1 to c5 and amt1 to amt5 would be better declared as two arrays (c and amt) of 1..MAX instead of 10 variables. When user inputs the amount, use it determine the section number which then can be used as the index into the c and amt arrays.
Not sure what implementation of Pascal you're using but it would be safer to initialize all variables before use otherwise they could contain unpredictable values.
The sections array is unnecessary. All it ends up containing is the title of the section which doesn't need to be calculated or stored.
If you used a repeat/until loop instead of a while loop, it would avoid the slightly kludgy "amount := 1" initialization at the top to enter the while loop. The repeat/until would be until Amount = 0.
TotalMas is only adding c1 to c3 (what about c4 and c5)?
TotalAmt is only adding amt1 to amt3 (what about amt4 and amt5)?
The for-loop to print the names and section is completely wrong, see points 1 and 4.
Hope this helps and let me know if you need clarification on any points.
My gripes with this code:
1) The variable names stink. Virtually all of them are way too short, they do not communicate what they do.
2) The wrong loop control structure is used here.
3) I see virtually identical code repeated 5 times. This is simply crying out for arrays.
4) The comments explain what you are doing, not why you are doing it. Half of them are virtually completely useless, if you're going to comment an end you should simply comment it with the identity of whatever it's an end to. end; //if I see only one comment that even tries to explain why and you've got it wrong as you're mixing up people with sections.
5) Your sections array accomplishes nothing useful. The assignments to the values are always fixed and thus there is no reason to store them at all--if you need the labels you can create them at print time.
6) You are assuming there are only going to be 5 people. That's not given in the problem--there's 5 sections.

Resources