2
\$\begingroup\$

I wrote this program that counts the number of letters in random.txt file in the Pascal programming language.
It doesn't matter if the letters are capitalized. Other characters are ignored. When it finishes it writes every letter in a single line and then after it the number of appearences of that letter in the text file.

program letters;
var 
random:text;
a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1:integer;
procedure counting(random:text; var a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1:integer);
var 
c:char;
begin
a1:=0;
b1:=0;
c1:=0;
d1:=0;
e1:=0;
f1:=0;
g1:=0;
h1:=0;
i1:=0;
j1:=0;
k1:=0;
l1:=0;
m1:=0;
n1:=0;
o1:=0;
p1:=0;
q1:=0;
r1:=0;
s1:=0;
t1:=0;
u1:=0;
v1:=0;
w1:=0;
x1:=0;
y1:=0;
z1:=0;
while not eof(random) do
while not eoln do
begin
if (c='A') or (c='a') then a1:=a1+1;
if (c='B') or (c='b') then b1:=b1+1;
if (c='C') or (c='c') then c1:=c1+1;
if (c='D') or (c='d') then d1:=d1+1;
if (c='E') or (c='e') then e1:=e1+1;
if (c='F') or (c='f') then f1:=f1+1;
if (c='G') or (c='g') then g1:=g1+1;
if (c='H') or (c='h') then h1:=h1+1;
if (c='I') or (c='i') then i1:=i1+1;
if (c='J') or (c='j') then j1:=j1+1;
if (c='K') or (c='k') then k1:=k1+1;
if (c='L') or (c='l') then l1:=l1+1;
if (c='M') or (c='m') then m1:=m1+1;
if (c='N') or (c='n') then n1:=n1+1;
if (c='O') or (c='o') then o1:=o1+1;
if (c='P') or (c='p') then p1:=p1+1;
if (c='Q') or (c='q') then q1:=q1+1;
if (c='R') or (c='r') then r1:=r1+1;
if (c='S') or (c='s') then s1:=s1+1;
if (c='T') or (c='t') then t1:=t1+1;
if (c='U') or (c='u') then u1:=u1+1;
if (c='V') or (c='v') then v1:=v1+1;
if (c='W') or (c='w') then w1:=w1+1;
if (c='X') or (c='x') then x1:=x1+1;
if (c='Y') or (c='y') then y1:=y1+1;
if (c='Z') or (c='z') then z1:=z1+1;
end;
close(random);
end;
procedure result(a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1:integer);
begin
writeln('A','',a1);
writeln('B','',b1);
writeln('C','',c1);
writeln('D','',d1);
writeln('E','',e1);
writeln('F','',f1);
writeln('G','',g1);
writeln('H','',h1);
writeln('I','',i1);
writeln('J','',j1);
writeln('K','',k1);
writeln('L','',l1);
writeln('M','',m1);
writeln('N','',n1);
writeln('O','',o1);
writeln('P','',p1);
writeln('Q','',q1);
writeln('R','',r1);
writeln('S','',s1);
writeln('T','',t1);
writeln('U','',u1);
writeln('V','',v1);
writeln('W','',w1);
writeln('X','',x1);
writeln('Y','',y1);
writeln('Z','',z1);
end;
begin
 assign(random,'random.txt');
 reset(random);
 counting(random,a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1);
 result(a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1);
 readln();
end.

I'm a beginner and I suppose this can be done a lot better and simpler without having to use 26 variables. How could I improve my code to make it work better? Could you give me some tips?

yuri
4,5383 gold badges19 silver badges40 bronze badges
asked Jul 6, 2017 at 15:40
\$\endgroup\$
5
  • \$\begingroup\$ Did you consider to use an array? You will drop 80% of your code \$\endgroup\$ Commented Jul 6, 2017 at 17:15
  • \$\begingroup\$ Yes, but I didn't know how to use it in this situation. Could you tip me how? @AdrianoRepetti \$\endgroup\$ Commented Jul 6, 2017 at 18:02
  • \$\begingroup\$ I wrote my last line in pascal almost 25 years ago, I do not think I will write decent code. Outline: keep an array of 24 elements. Check if each char is c >= 'A' and c <= 'Z' and in case subtract 'A' to get index of array. Increment item at that index by 1. If your library does not have a tolower() function then repeat for a. Then use proper indentation and meaningful names (random as parameter name? Why?) \$\endgroup\$ Commented Jul 6, 2017 at 18:51
  • \$\begingroup\$ " in case subtract 'A' to get index of array." - I didn't quite get this part. Regarding random as name, it's because I'm not a native english speaker, I had a more meaningful name in my language but I changed it so I could post it here. @AdrianoRepetti \$\endgroup\$ Commented Jul 6, 2017 at 19:03
  • \$\begingroup\$ rosettacode.org/wiki/Letter_frequency#Pascal but in your case you need few lines more because calculation is case insensitive and you want to consider only Latin characters (subtract A means subtract its ASCII value, 65) \$\endgroup\$ Commented Jul 6, 2017 at 19:25

1 Answer 1

2
\$\begingroup\$
  • Declaring 26 individual counter variables: Now this is generally considered bad style. These 26 variables fulfill a common purpose, yet they are completely independent from each other. A simple solution would at least use

    var
     chart: array[char] of integer;
    

    Now this is quite wasteful, because the range chr(0)..maxChar which we’re using for this array’s first and only dimension contains lots of unused entries. Specifically, both chart['A'] and chart['a'] coexist. We can remediate this situation and declare an array containing only 26 integer values, or we can leave this as is and simply print chart['A'] + chart['a'] in our final printing procedure.

  • procedure counting(random:text; [...]
    

    Parameters of the data type file of ... (including parameters of the data type text) always must be passed as var parameters. Any decent compiler will reject your code.

  • var 
    random:text;
    a1,...,z1:integer
    procedure counting(random:text; var a1,...,z1:integer);
    [...]
    procedure result(a1,...,z1:integer);
    

    Now this shows that you have not understood the concept of scopes. Because you have declared your variables before the definitions of counting and result, you can access them directly in counting and result. There is no need to pass all variables in parameters. The entire parameter list could be left out and your program would still work (you, of course, have to adjust the calls below accordingly).

    Generally speaking, global variables, i. e. the declaration of variables before any routines, is considered bad. I would simply move the var-section you have down below the procedures, right before the program’s "main" begin ... end.

  • a1:=0;
    ...
    z1:=0;
    

    If you had an Extended Pascal (ISO standard 10206) compliant compiler, you could specify an initial value at the variable declaration, like so:

    var
     a1, b1, c1: integer value 0;
    
  • You do not read anything in the reading loop:

    while not {EOF / EOLn respectively} do
    [...]
    end;
    

    Is an infinite loop, because your "reading cursor" remains at the same position. There is no read(random, c). This also means your c remains uninitialized. You’re reading an uninitialized value which is very bad.

  • In Pascal the expression

    (c='A') or (c='a')
    

    is usually written as

    c in ['A', 'a']
    
  • Since any Boolean expression can be converted into an integer using ord, you could rephrase your line(s)

    if (c='A') or (c='a') then a1:=a1+1;
    

    to

    a1 := a1 + ord(c in ['A', 'a']);
    

    This will add 0 or 1 to a1. Some people find this more elegant instead of single-line if ... thens.

  • writeln('A','',a1);
    

    Writing an empty string ('') has no effect. Maybe you wanted append a minimum width specifier to create a tabular look?

    writeLn('A', '':4, a1);
    
answered Oct 18, 2022 at 16:00
\$\endgroup\$
3
  • \$\begingroup\$ Thanks for this great answer - I hope to see more from you in future! \$\endgroup\$ Commented Oct 18, 2022 at 16:12
  • 1
    \$\begingroup\$ @TobySpeight Unfortunately there are very few pascal code review requests. It’s already weird to respond to a five year old request. Frankly I think Plexus (the requester) would not write such code today, so he does not need any feedback (anymore). \$\endgroup\$ Commented Oct 18, 2022 at 19:27
  • \$\begingroup\$ There are also few Pascal answerers, which makes your contribution the more welcome! Answering old questions is fine, as we aim to help all programmers improve their code (not just the askers), so please do continue doing that. I find that answering (in the languages I know - it's over 30 years since I touched any Pascal) also improves my own skills, too. \$\endgroup\$ Commented Oct 19, 2022 at 6:47

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.