friar tux has asked for the wisdom of the Perl Monks concerning the following question:

########################################################## #

hi, I am new to perl and am trying to build a grade # #calculator.I have gone through the code for hours and am# #stuck. can some one point me in the right direction? it # #looks to me like it should be running.

########################################################## #

located in = /var/www/htdocs/index.html

###########################################################
<html> <head></head> <form action=/cgi-bin/math4.cgi method=post> <center> <h1>Grade Calculator</h1> task1:<input type=text name=g1 maxlength=3 size=3><br> task2:<input type=text name=g2 maxlength=3 size=3><br> task3:<input type=text name=g3 maxlength=3 size=3><br> task4:<input type=text name=g4 maxlength=3 size=3><br><br> <h1>How to's</h1> <br> 0<input type=radio value=0 name=g5><br> 25<input type=radio value=25 name=g5><br> 50<input type=radio value=50 name=g5><br> 75<input type=radio value=75 name=g5><br> 100<input type=radio value=100 name=g5><br> <h1> Attitude</h1> <select name=g6> <option>0</option> <option>25</option> <option>50</option> <option>75</option> <option>100</option> </select><br><br> <br><input type=reset><br> <input type=submit> </center> </body> </form> </html>
############################################################ #

located var\www\cig-bin\math4.cgi|chmod 755 math4.cgi

###########################################################
#!/usr/bin/perl use CGI ':standard'; $g1=param('g1'); $g2=param('g2'); $g3=param('g3'); $g4=param('g4'); $g5=param('g5'); $g6=param('g6'); $letter; $average; $div; $total=($g1 + $g2 + $g3 + $g4 + $g5 + $g6); sub div{ if($g1 ne ''){$div++;} if($g2 ne ''){$div++;} if($g3 ne ''){$div++;} if($g4 ne ''){$div++;} if($g5 ne ''){$div++;} if($g6 ne ''){$div++;} } $average=($g1 + $g2 + $g3 + $g4 + $g5 + $g6) / $div; sub letter{ if ($average > 100) {print "illegal average, check your grades";} if($average > 92.5){$letter="A"; } elsif($average > 89.5){$letter="A-"; } elsif($average > 87.5){$letter="B+"; } elsif($average > 82.5){$letter="B"; } elsif($average > 79.5){$letter="B-"; } elsif($average > 76.5){$letter="C+"; } elsif($average > 72.5){$letter="C"; } elsif($average > 69.5){$letter="C-"; } elsif($average > 66.5){$letter="D+"; } elsif($average > 62.5){$letter="D"; } elsif($average < 62.4){$letter="F"; } print " <li> the letter grade is $letter <br /> "; }
############################################################ #

sorry if this post is to big or asked incorrectly I am #still learning. #I ran the math4.cgi through shell console and no errors #came up except that dividing by zero was an illegal #command.when I run localhost through fire fox the html #works but I get the ocal server error screen and it says it #can't find math4.cgi in the cgi-bin directory. #any help is appreciated.

###########################################################

Replies are listed 'Best First'.
Re: grade calulator coding problem
by toolic (Bishop) on Mar 06, 2011 at 20:41 UTC
    I have no experience with such things, but perhaps Troubleshooting Perl CGI scripts will help you.

    Unrelated to your problem... a loop can make your code more scalable and less error-prone (UNTESTED):

    use CGI ':standard'; use warnings; use strict; my $total = 0; my $div = 0; for (1 .. 6) { my $g = param('g' . $_); if ($g ne '') { $total += $g; $div++; } } die "Error: div by 0" if $div == 0; my $average = $total/$div;
Re: grade calulator coding problem
by NetWallah (Canon) on Mar 06, 2011 at 22:46 UTC
    You have DECLARED your subroutines, but not CALLEd them.

    The code works if you add the calls around the "$average" caclulation, like:

    div(); # CALL the sub named div $average=($g1 + $g2 + $g3 + $g4 + $g5 + $g6) / $div; letter(); #CALL the sub named letter
    Of course, as others have pointed out, there is much room for code and coding style improvement.

    Update:Here is a more concise, and idomatic version:

    #!/usr/bin/perl use strict; use CGI qw|:standard|; my ($count,$total); my @gradeletter = qw| A A- B+ B B- C+ C C- D+ D |; # no F because that + is default; my @gradeval = qw|92.5 89.5 87.5 82.5 79.5 76.5 72.5 69.5 66.5 62.5 |; for(1..6){ my $value = param ("g$_"); $count++ if $value > 0; $total += $value; } $count ||=1; # Avoid divide by zero my $average = $total / $count; my $letter = "F"; # Default , unless a better one is found for (0..$#gradeletter){ if ($average > $gradeval[$_]){ $letter = $gradeletter[$_]; last; } } $letter = "INVALID" if $average > 100; print ul(li(" The letter grade is $letter" )), "\n";

         Syntactic sugar causes cancer of the semicolon.        --Alan Perlis

Re: grade calulator coding problem
by TomDLux (Vicar) on Mar 06, 2011 at 21:04 UTC

    I'm confused about what you are actually trying to achieve.

    If the goal is to experiment with cgi scripts, or to satisfy some computer class homework assignment, this approach is fine. However, I hardly think entering 6 partial scores into a web page is the practical way to maintain grades for a class.

    A spreadsheet is the obvious solution to the problem: MS Excel, GNU Gnumeric, Open Office Calc, or some other equivalent. One row for each student, one column for each landmark / assignment / test. Enter data for a column as each assignment / test is graded, and a column at the right will calculate the current total.

    On a school-wide basis it would make sense to have a database, in which case you might enter the scores for all the students on assignment X at one time. But after that, no need for the user to enter the marks, the program can look them up from the database.

    As Occam said: Entia non sunt multiplicanda praeter necessitatem.

Re: grade calulator coding problem
by friar tux (Novice) on Mar 07, 2011 at 03:38 UTC

    Thanks for all your help guys. I learned more about perl today than I thought I would but it still isn't working. I am still getting the "internal server error screen"I tried all of your advice separately and tried the code Netwallah had written but still getting the error screen even though it runs fine in the shell -konsole I am going to try some simpler scripts and try to work my way through to see if I can find the problem. thanks again for the help I appreciate any help I can get.

      "Internal server error" is a web server error message. More detail will be in the web server logs - typically, this will be in /var/log/httpd/error.log .

      The most common cause is that you forgot to set the script permission to 755, or did not place it in an appropriate cgi-bin directory.

           Syntactic sugar causes cancer of the semicolon.        --Alan Perlis

        Thanks!! I found the error log and I almost understand what it says I assume it has something to do with the last line of the script. +Sun Mar 06 22:58:45 2011 error client 127.0.0.1 malformed header from script. Bad header=

        • The letter grade is C: calc.cgi, referer: http://localhost/ I am still using the script you wrote because its very well written. I will type up my own version of it once I get this one working I just learn better if I have a working copy to start with then I take it and learn how it works. anyway I am going to mess with the last line and see if I can get it running. you have been very helpful thank you