Pascal Pseudocode - pascal

I'm learning Pascal Pseudocode in school and my teacher sent me this exercise:
Write an algorithm, in pseudocode, that, when read the name and the ages for N students, counts how many of them have more than 18 years old. Should print the name of those students.
I've writen the code until printing the counting of those students, but how should I do to print their names. Can you guys give me a tip?
PS: I didn't learned anything of arrays or records.
BEGIN
WRITE ('Insert the number of students in the class.');
READ (n);
i := 1;
WHILE i<=n DO
BEGIN
WRITE ('Insert the student's name');
READ (name);
WRITE ('Insert the student's age');
READ (age);
IF age > 18 THEN
count := count + 1;
i := i + 1;
END;
WRITE ('There are ',count,' students with more than 18 years.');
I cannot proceed from here.

You had several errors, you read the variables with READ instead of with READLN and I assume that the variables you have already declared. On the other hand the if it is convenient to have closure (with END)
Finally, remember to "stop" the console so that the message can be displayed
program count_age;
USES CRT;
VAR i,age,count,n:INTEGER;
VAR name:STRING;
BEGIN
count :=0;
WRITE ('Insert the number of students in the class. ');
READLN (n);
i := 1;
WHILE i<=n DO
BEGIN
WRITE ('Insert the students name ');
READLN (name);
WRITE ('Insert the students age ');
READLN (age);
IF age > 18 THEN BEGIN
count := count + 1;
END;
i := i + 1;
WRITE ('There are ',count,' students with more than 18 years.');
readkey;
END.

Related

ORA-06533: Subscript beyond count ORA-06512 in PL/SQL

i want to have 10 by 10 grid with numbers from 1 to 100
and it give me this error
ORA-06533: Subscript beyond count ORA-06512: at line 25
ORA-06512: at "SYS.DBMS_SQL", line 1721
i don't understand the error and i couldn't solve it
can someone please help me
DECLARE
-- PL SQL code to create and fill a two-dimensional array
-- create VARRAY type of 10 integers
TYPE array_10_int IS VARRAY(10) of PLS_INTEGER;
-- create VARRAY type of array_10_int
TYPE grid_100_int IS VARRAY(10) of array_10_int;
-- declare a variable of the grid_100_int type
grid_var grid_100_int;
-- declare counters
i PLS_INTEGER := 0;
j PLS_INTEGER :=0;
M PLS_INTEGER :=0;
N PLS_INTEGER :=0;
BEGIN
grid_var := grid_100_int();
-- TO DO : use nested loop to fill grid_var with numbers 1- 100
/** YOUR CODE HERE **/
M:=0;
Loop
M:=M+1;
N:=0;
LOOP
J:=j+1;
If grid_var(M)(N)<100 THEN
DBMS_OUTPUT.PUT(' ' || grid_var(M)(N) || ' ');
ELSE
DBMS_OUTPUT.PUT( grid_var(M)(N) || ' ');
END IF;
EXIT WHEN (N =100);
END LOOP;
dbms_output.put_line(' ');
EXIT WHEN (M=10);
END LOOP;
-- Print the grid with nested loop
i:=0;
LOOP --outer loop
i := i+1;
j := 0;
LOOP -- inner loop
j:= j+1;
IF grid_var(i)(j) < 10 THEN
DBMS_OUTPUT.PUT(' ' || grid_var(i)(j) || ' ');
ELSE
DBMS_OUTPUT.PUT( grid_var(i)(j) || ' ');
END IF;
EXIT WHEN (j =10);
END LOOP;
dbms_output.put_line(' ');
EXIT WHEN (i =10);
END LOOP;
END;
A second look.
Creating multiple dimensional arrays (10 x 10) are tricky things. They are actually a collection of a collection. Further, each has the same definition and existence requirements: the element must exist before referenced, either by extend or array initialization. The following initializes each array before referencing it. Also it uses a FOR loop letting Postgres handle the setting, incrementing subscripts and loop exiting, rather than manually. See demo.
declare
-- PL SQL code to create and fill a two-dimensional array
-- create VARRAY type of 10 integers
type array_10_int is varray(10) of pls_integer;
-- create VARRAY type of array_10_int
type grid_100_int is varray(10) of array_10_int ;
-- declare a variable of the grid_100_int type
grid_var grid_100_int;
begin
grid_var := grid_100_int(null,null,null,null,null,null,null,null,null,null); -- initialize outer array
-- TO DO : use nested loop to fill grid_var with numbers 1- 100
/* YOUR CODE HERE */
for m in 1 .. 10
loop
grid_var(m) := array_10_int(null,null,null,null,null,null,null,null,null,null); -- initialize the inner array
for n in 1 .. 10
loop
grid_var(m)(n) := 10*(m-1)+ n;
end loop ;
end loop;
-- Print the grid with nested loop
for m in 1 .. 10
loop
for n in 1 .. 10
loop
dbms_output.put_line ('grid_var(' || to_char(m)
|| ')(' || to_char(n)
|| ') = ' || to_char(grid_var(m)(n))
);
end loop ;
end loop;
end;
Take away: Creating and using multiple dimensional arrays in Oracle is doable. But use them only when there is no other option. They add considerable complexity, usually unnecessary, and are poorly understood. (The above one is vary simple.)
Take away 2 Let Postgres control your loops. Less error prone, less code, easier to read.
PL/SQL array index begin with 1. But in the following code the local variable n is 0 when first used as an index.
Loop
M:=M+1;
N:=0;
LOOP
J:=j+1;
If grid_var(M)(N)<100 THEN --<<< n is 0 which throws your exception.
...
EXIT WHEN (N =100); --<<< NEVER occurs, N is not
Unfortunately, this is not your only issue (in this logic). You exit statement is condition EXIT WHEN (N =100); will never be met. You initialize the variable n before entering the loop, but never increment it in the loop.
Adjust the above to:
Loop
M:=M+1;
N:=1; -- <<< change here
LOOP
J:=j+1;
If grid_var(M)(N)<=100 THEN
...
EXIT WHEN (N >100); --<<< NEVER occurs, N is not incremented in the loop;
END LOOP;
Your other loop does not appear to have the same issue, but you should check it.

unknown runtime error in pascal

I am unable to locate the source of this error that i keep getting in my coding for school. Every time i enter one value in my array and the for loop runs it either encounters a runtime error or the rest of the program runs based on information from the first value and doesn't accept any other values. Can someone please explain to me how to fix this?
program Montserrat_Elections;
Var cndnme : array [1..4] of String;
votes : array [1..4] of Integer;
highest, cnt : Integer;
winner : string;
begin
highest:= 0;
winner:= 'Dan';
For cnt:= 1 to 4 do
begin
Writeln('Please enter the first name of the candidate and the number of votes');
Read (cndnme[cnt], votes[cnt]);
If votes[cnt] > highest then
highest := votes[cnt];
winner := cndnme[cnt];
end;
Writeln('The winner of this constituency is', winner, 'with', highest, 'votes')
end.
Change Read to Readln :
Readln (cndnme[cnt], votes[cnt]);
Then you need add begin...end; to this line:
If votes[cnt] > highest then
begin
highest := votes[cnt];
winner := cndnme[cnt];
end;
I update & test your codes :
program Montserrat_Elections;
Var cndnme : array [1..4] of String;
votes : array [1..4] of Integer;
highest, cnt : Integer;
winner : string;
begin
highest:= 0;
winner:= 'Dan';
For cnt:= 1 to 4 do
begin
Writeln('Please enter the first name of the candidate and the number of votes');
readln(cndnme[cnt], votes[cnt]);
If votes[cnt] > highest then
begin
highest := votes[cnt];
winner := cndnme[cnt];
end;
end;
Writeln('The winner of this constituency is ', winner, ' with ', highest, ' votes');
readln;
end.
Result:
Please enter the first name of the candidate and the number of votes
Me
23
Please enter the first name of the candidate and the number of votes
You
42
Please enter the first name of the candidate and the number of votes
Ainun
18
Please enter the first name of the candidate and the number of votes
Jhon
38
The winner of this constituency is You with 42 votes

Pascal multiple records being passed into a function

This is my code:
type
TStudent = record
Firstname:string[15];
Surname:string[15];
dateofbirth:tdatetime;
gender: char;
ASmark: integer;
end;
var student: array [1..10] of tstudent;
option:integer;
...
function readrecord:tstudent;
var //dob:string;
i:integer;
begin
for i := 1 to 10 do
begin
Writeln('Enter Firstname for student ',i, ' : ');
readln(student[i].firstname);
Writeln('Enter Surname ',i, ' : ');
readln(student[i].Surname);
writeln('Enter Date of Birth ',i, ' : ');
//readln(dob);
//student[i].dateofbirth:=strtodate(dob);
Writeln('Enter Gender (M or F) ',i, ' : ');
readln(student[i].gender);
Writeln('Enter AS Mark ',i, ' : ');
readln(student[i].ASmark);
end;
end;
DOB is commented out for now, don't worry about that :)
procedure averagemark(var student:tstudent);
var mark:real;i:integer;
begin
mark:=0;
for i := 1 to 10 do
begin
mark:=mark+(student[i].asmark);
end;
mark:=(mark/10);
writeln('Average mark: ',mark:5:2);
end;
I am trying to get an average of the asmark, but I get errors for mark:=mark+(student[i].asmark); which are Error: no default property available and Fatal: Syntax error,")" expected but "[" found.
It would be much appreciated if someone could point me in the right direction as I have tried quite a lot of things and also researched.
I also created a data type called tstudenta which was an array of the tstudent record, then set student:tstudentr; but had no luck here either.
procedure averagemark(var student: tstudent);
You pass a single record here instead of an array. Use an open array:
procedure averagemark(const students: array of tstudent);
Loop from low(students) to high(students) rather than hard coding the array bounds.
If your Pascal dialect does not support open arrays, then you should use an array. If it suffices to use an array with a fixed length of 10 then you could define the array type like so:
type
TStudentArray = array [1..10] of TStudent;
You'd then use that type for the parameter of your procedure:
procedure averagemark(const students: TStudentArray);
It's a little tricky to be specific without more knowledge of your particular Pascal dialect. However, the essence is as I have said. You need to pass an array of records rather than a single record.

Redefine variables which names depends of what user enters

I have some variables ordered by numebers, like ex1,ex2,ex3,etc (integers); i'd like to count how many times the user enter a letter of a number in a way such that if '1' is entered the program adds +1 to ex1, if 2 is enteres the program adds +1 to ex2- and so on (I can't use arrays because it's forbidden in the excersise). For example, if i ask the user to enter 15 numbers between 1 and 15, and i would like to count how many times each one of those is entered, the code i'm thinking of would be something like
for i:=1 to 15 do
read(number);
if number = i then
Begin
exi := exi + 1;
End
Obviously that didn't work. Is it possible to redefine a variable doing something similar?.
If you can't use arrays at all, you have just a couple of choices.
A case statement
for i := 1 to 15 do
begin
Read(number);
case number of
1: ex1 := ex1 + number;
2: ex2 := ex2 + number;
// rest of possible values and variables
else
// Handle number that doesn't have a variable
end;
end;
if..else statements
for i := 1 to 15 do
begin
Read(number);
if number = 1 then
ex1 := ex1 + number
else if number = 2 then
ex2 := ex2 + number
else if // rest of possible values and variables
else // Handle number that doesn't have a variable
end;
end;

How to populate varray multiple times

I have a script that uses one VARRAY multiple times. But, I can't seem to figure out how to reset the VARRAY after looping through it once. I wrote the following basic script to help me troubleshoot:
DECLARE
TYPE multi_show_id_type IS VARRAY (60) OF VARCHAR2 (10);
multi_show_id multi_show_id_type := multi_show_id_type ();
counter NUMBER := 1;
i NUMBER := 1;
BEGIN
DBMS_OUTPUT.put_line ('BEGIN');
WHILE i < 10
LOOP
DBMS_OUTPUT.put_line (i);
--counter:=0;
--multi_show_id :=multi_show_id_type();
--multi_show_id.delete;
WHILE counter < 25
LOOP
multi_show_id.EXTEND ();
multi_show_id (counter) := counter * counter;
DBMS_OUTPUT.put_line ('VArray: [' || counter || '] [' || multi_show_id (counter) || ']');
counter := counter + 1;
END LOOP;
i := i + 1;
END LOOP;
DBMS_OUTPUT.put_line ('END');
END;
/
This script works when it is only looping through the array once. But if you uncomment the counter:=0 line, which forces it to loop through the array population loop 10 times, I get an ORA-06532 error. You can see some of the stuff I've tried in the other commented lines. Any help would be appreciated.
Actually, #akf is correct; your code as written won't work because a VARRAY starts at item 1, not zero.
Change your code thusly and it works:
...
LOOP
DBMS_OUTPUT.put_line (i);
counter:=1;
--multi_show_id :=multi_show_id_type();
multi_show_id.delete;
WHILE counter < 26
LOOP
...
EDIT: if you want to run thru the loop 25 times you do need to change the WHILE loop upper bound to 26...
there seems to be two problems here. first, the VARRAY index starts at 1. second, you will stop once your VARRAY is full at 60 items, as defined in your declaration.
use the following:
TYPE multi_show_id_type IS VARRAY (250) OF VARCHAR2 (10);
and
counter:=1;
uncomment the multi_show_id :=multi_show_id_type(); line if you want to start at 1 for each loop. if you want to ensure that no more than 4 values, your inner while loop should make that restriction.

Resources