Solved

PASCAL Array problem / question

Posted on 2008-10-29
21
1,179 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 7
  • 5
  • +1
21 Comments
 
LVL 19

Expert Comment

by:MerijnB
ID: 22830086
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
ID: 22830095
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
ID: 22830113
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:AACCosmos
ID: 22830457
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
ID: 22830575
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
ID: 22830618
what do you mean with crash, what error msg?
0
 
LVL 1

Author Comment

by:AACCosmos
ID: 22830641
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
ID: 22830660
are you sure FreqTot isn't 0 at that moment?
0
 
LVL 1

Author Comment

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

Expert Comment

by:MerijnB
ID: 22830720
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
 
LVL 19

Expert Comment

by:MerijnB
ID: 22830734
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
ID: 22830947
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
ID: 22830964
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
ID: 22830962
I ment i did: If score <> 11 then
0
 
LVL 19

Expert Comment

by:MerijnB
ID: 22830972
LOL,

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

Expert Comment

by:BigRat
ID: 22831001
>>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
ID: 22831106
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
ID: 22831222
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
ID: 22831290
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
ID: 22831669
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
ID: 22834721
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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…

732 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