Solved

PASCAL Array problem / question

Posted on 2008-10-29
21
1,166 Views
Last Modified: 2012-05-05
Hi there!

I'm very new to pascal, and currently have a issue with array programming... I need to make a tool for a teacher where he can add all testscores into a array, and calculate how many people have scores lower then 5, higher then 5, and whats the avarage score. This is not a homework assignment btw, I'm just trying to learn and understand how to fix problems with array solutions.

I made this code now but something is not good and i cant get a hold of it... Are there any PASCAL gurus out here who can give me a bit of help? :)

So the table sort of needs to look like this and i need to do some calculations based on the indexes:

Points:           1   2   3   4  5   6   7   8   9   10
Frequency:    0   1   4   5  6   9   3   2  1    1

I was able to come up with the following code but its still wrong.. What am i doing wrong here?

Var   freq: Array[1..10,0..1] of integer;
      GoodScore, BadScore, FreqTot, Points, Total : Integer;
      Avarage : Real;
begin
  try

BadScore := 0;
while Points <= 10 do
   begin
   for Points := 1 to 10 do;
      for FreqTot := 0 to 1 do;
         Freq[Points,FreqTot] := 0;
   Points := 1;
   FreqTot := 0;
   while Points <= 10 do
      Write ('give Points: ');
      Readln (Points);
      Total := Total + Points * Freq[Points];
      if Points <= 5
      then BadScore := BadScore + Freq[Points];
      Points = Points + 1;
   end;
Avarage := Total / FreqTot;
GoodScore := 0;
Points = 10;
While Points > Avarage do
    begin
    GoodScore := GoodScore + Freq[Points];
    Points := Points -1;
    end;
Write (GoodScore) (Avarage) (BadScore);
Readln;

  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
0
Comment
Question by:AACCosmos
  • 8
  • 7
  • 5
  • +1
21 Comments
 
LVL 19

Expert Comment

by:MerijnB
Comment Utility
What is going wrong, do you get an exception or do you have a functional bug?
Why is the array 2 dimensional?
0
 
LVL 27

Accepted Solution

by:
BigRat earned 250 total points
Comment Utility
If the scores are limited to integer values between 0 (total fail) and 10 (all correct), then the "score" is an index to an array, which holds the frequencies :-

var
    frequencies : array[0..10] of Integer;

The FIRST thing to do is to clear the array :-

    for i:=0 to 10 do frequencies[i]:=0;

Then read in the scores, terminating say by -1, :-

   Writeln(Output,'Please enter scores, the last one being -1');
   repeat
       score:=readln(Input);
       (* if the score is NOT -1 add to the list *)
       if (score>=0) and (score<=10) then
          frequencies[score]:=frequencies[score]+1;
       if score>10 then
          Writeln(Output,'invalid score (>10), please enter again or -1 to terminate');
   unitl score<0;

And then you can work out whatever data you want from the data in the array.
For example, the number of scores less than five :-
     lessThanFive:=0;
     for i:=0 to 4 do
          lessThanFive:=lessThanFive+frequencies[i];

There are several techniques which you should notice :-

1. Keep data structures simple.
2. Always initialize you data before doing anything else.
3. Separate input from calculation.
4. Do calculations separately.

The last two points separate functionality, which enables you to simply add more. Doing the input with the calculation leads to unlcear and messy code.
0
 
LVL 27

Expert Comment

by:BigRat
Comment Utility
One point with your code, AACCosmos, there is NO semicolon after the do :-

         for Points := 1 to 10 do;

that makes the loop do nothing!.

And sorry, my input should read Readln(Input,score) and NOT score:=readln(Input);
0
 
LVL 1

Author Comment

by:AACCosmos
Comment Utility
Hey BigRat,

Thanks a lot for the help, this is good stuff in helping me to understand how this works.

One last question though, I dont understand this part: Readln(Input,score)

Where does that variable input come from, why is it there, and what is its purpose?
0
 
LVL 1

Author Comment

by:AACCosmos
Comment Utility
I would like to add one more question to my previous, then I'll quit stalking here and give out the points :)

I made my own code to give it my personal flavour and for better personal understandig at this moment. But there's still a bug. The code looks like this now:

Var   freq: Array[1..10] of integer;
      Score,i,GoodScore, BadScore, FreqTot, Points, Total : Integer;
      Avarage : Real;
begin
  try
for i:=1 to 10 do freq[i]:=0;
Total := 0;
BadScore := 0;
FreqTot:= 0;
Score := 1;

while Score <= 10 do
   Begin
     writeln ('Please enter score, you can exit with 11: ');
     Readln (Score);
     Total := Total + Score * Freq[Score];
     FreqTot := FreqTot + Freq[Score];
     if Score <= 5 then BadScore := BadScore + Freq[Score];
     Score := Score + 1
   End;

GoodScore := 0;
Score := Score -1;
Avarage := Total/FreqTot;
while Score > Avarage do
   begin
   GoodScore := GoodScore + Freq[Score];
   Score := Score - 1
   end;
Writeln ('Goodscore = : ', GoodScore, 'Avarage = : ', Avarage:0:2, 'BadScore = : ', Badscore);
Readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

The program starts, and I can enter all information, but as soon as i hit 11 it crashes with the breaking point at this "Avarage := Total/FreqTot;".  What am i still missing here?
0
 
LVL 19

Expert Comment

by:MerijnB
Comment Utility
what do you mean with crash, what error msg?
0
 
LVL 1

Author Comment

by:AACCosmos
Comment Utility
Hi MerijnB,

This is the error message:

Project Project3.exe raised exeption class EInvalidOp with message 'Invalid floating point operation'.

Thanks a lot!
0
 
LVL 19

Expert Comment

by:MerijnB
Comment Utility
are you sure FreqTot isn't 0 at that moment?
0
 
LVL 1

Author Comment

by:AACCosmos
Comment Utility
I dont think so because I enter for example 10 different scores so it should have changed?
0
 
LVL 19

Expert Comment

by:MerijnB
Comment Utility
It's because of this part:

while Score <= 10 do
   Begin
     writeln ('Please enter score, you can exit with 11: ');
     Readln (Score);
     Total := Total + Score * Freq[Score];

do something like
while Score <= 10 do

   Begin

     writeln ('Please enter score, you can exit with 11: ');

     Readln (Score);

     if Score = 11 then

      halt(0); {quit}

     Total := Total + Score * Freq[Score];

Open in new window

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 19

Expert Comment

by:MerijnB
Comment Utility
basically with this line

Total := Total + Score * Freq[Score];

you write beyond your array

freq: Array[1..10] of integer;

when Score = 11
0
 
LVL 1

Author Comment

by:AACCosmos
Comment Utility
Hi Merijn,

Once again thanks for the help. When I add that line the program just quits and I dont see the result. I realise i need to find a method to exit that loopt without writing beyong my array.

I tried this now:

while Score <= 10 do
   Begin
     writeln ('Please enter score, you can exit with 11: ');
     Readln (Score);
     if score = 11 then
        begin
        Total := Total + Score * Freq[Score];
        FreqTot := FreqTot + Freq[Score];
        if Score <= 5 then BadScore := BadScore + Freq[Score];
        Score := Score + 1
        end;

But still no luck, exactly the same error :)
0
 
LVL 19

Assisted Solution

by:MerijnB
MerijnB earned 250 total points
Comment Utility
Since you do _not_ want this code to be run when it's 11 it should be
while Score <= 10 do

   Begin

     writeln ('Please enter score, you can exit with 11: ');

     Readln (Score);

     if score <> 11 then

        begin

        Total := Total + Score * Freq[Score];

        FreqTot := FreqTot + Freq[Score];

        if Score <= 5 then BadScore := BadScore + Freq[Score];

        Score := Score + 1

        end;

Open in new window

0
 
LVL 1

Author Comment

by:AACCosmos
Comment Utility
I ment i did: If score <> 11 then
0
 
LVL 19

Expert Comment

by:MerijnB
Comment Utility
LOL,

show me the complete code you used to avoid miscommunications
0
 
LVL 27

Expert Comment

by:BigRat
Comment Utility
>>One last question though, I dont understand this part: Readln(Input,score)

This is an old habit of mine. The first parameter to the standard I/O routines is the file variable. They default to Input and Output if not mentioned explicitly. I mention them explicitly, it's just a habit. I've been programming in this language for nigh on thirty years now.

Secondly this bit of code breaks several rules :-

while Score <= 10 do
   Begin
     writeln ('Please enter score, you can exit with 11: ');
     Readln (Score);
     Total := Total + Score * Freq[Score];
     FreqTot := FreqTot + Freq[Score];
     if Score <= 5 then BadScore := BadScore + Freq[Score];
     Score := Score + 1
   End;

And then :-
First you don't test Score after the read to ensure that it is a proper value.
Second I suggested that you keep input and processing separate for clarity.
Third you don't actually write anything in the Freq array (ie: update it), so either want's the point in having it and what's the point in reading it?
Fouth the total is NOT calculated from ALL input but from bits of it. That's totally WRONG.
Fifth, why the "while/do Score" loop whith the kludge of assigning 1 to Score, when the DESIGN cries out for repeat/until?
0
 
LVL 1

Author Comment

by:AACCosmos
Comment Utility
Hi all again.. I'm so sorry for the confusion.. I understand your statements BigRat, but the problems are there because i'm still looking for solutions to fix them.

To comment your thoughts:

First: I realise I dont do test yet. This is stuff I will try to program as soon as i have a working tool :)
Second: I feel so stupid but.. I dont know how to do this yet... Which is why i'm learning and asking for advice :)
Third: That is probably the reason why my program still doenst work. But how do I write inside the freq array?
Fourth: I think this is solved when i fix point your third point right?
Fifth: Because I havent been tought yet how to use repeats :) According to the book I should be able to get this thing working without repeats.
0
 
LVL 27

Expert Comment

by:BigRat
Comment Utility
You are not only very new to Pascal but new to programming, since you keep making basic mistakes.
I have written 50% of the code for you, you should be able to take it from there, ie: add in the necessary declarations, compute the average etc.

>> According to the book I should be able to get this thing working without repeats.

This sounds extremely like a homework question. Yes, one can avoid almost any language construct that one wants, but the art of programming lies in using the most effective construct, and that is often the most clear.

As George Bernard Shaw once said, "In matters of great importance it is style, not sincerity, which is the thing".

I suggest you start with my code and continue along the same lines, because I can't solve homework questions.
0
 
LVL 1

Author Comment

by:AACCosmos
Comment Utility
Hi BigRat :)

All the respect to you for not trying to solve homework questions but in this case it really isnt. I'm preparing for a exam, and creating problems i need to solve myself now in order to learn more about arrays.

I think i have solved my problem now doing this:

while Score <= 10 do
   Begin
     writeln ('Please enter score, you can exit with 11: ');
     Readln (Score);
     if Score <> 11 then
        Begin
        Freq[Score] := Freq[Score] +1;
        Total := Total + Score * Freq[Score];
        FreqTot := FreqTot + Freq[Score];
        if Score <= 5 then BadScore := BadScore + Freq[Score];
        End;
   End;

With this piece of code added to the rest, the program seems to have its basic fucntionality working :) All thats left now is looking into repeats as you mentioned, since you have let me know it is a better method. After this i will try to add more checks.

A friend once told me, for every 10 rules of code you need to program 100 to check those 10 hehe.

:) Cheers m8, really appreciate the thoughts.
0
 
LVL 27

Expert Comment

by:BigRat
Comment Utility
First the program will break if somebody enters 12.
The line should read :-

if (Score>=0) and (Score<=10) then

ie: only process VALID data.

Second the total score is the totality of scores. So the line should read :-
 
                      Total := Total + Score;

Thirdly the number of bad scores (the variable for which should be designated NrBadScore) is the number of scores found to be less than five. So that line should read :-

if Score <= 5 then NrBadScore := NrBadScore + 1;

Lastly I'm not sure what FreqTot is meant to be? If you mean the number of scores entered, then that should be called NrScores and should be incremented by 1 each time a valid score is entered.
 
0
 
LVL 6

Expert Comment

by:JosephGlosz
Comment Utility
just to understand the principles. The reason for the crashes is that you declare an array of 1 to 10 and call it Freq. However this means there ARE only 10 array locations for Freq. Freq[1] through Freq[10].  If you try to access or use 'Freq[11]' or 'Freq[12]' in any way at all, it will crash because no such location exists.

That's why, when you enter an 11 or 12 it will crash unless you prevent that part of the code from executing.

So change this section of the code to look like:

      Readln (Points);
      if Points in [low(Freq)..high(Freq)] then
         begin
           Total := Total + Points * Freq[Points];
           if Points <= 5
             then BadScore := BadScore + Freq[Points];
          Points = Points + 1;
        end;
   end;

you can prevent wrongful access of Freq[x] with the line

      if Points in [low(Freq)..high(Freq)] then


 
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now