Question:
How to solve the issue of producing the wrong output value in PHP?

Problem

I wrote the PHP code that calculates the school grade (including weight and targeting rate), however, it produces the wrong output value.


Here's the PHP code so far


<?php


$numassignments = isset($_GET['numassignments']) ? $_GET['numassignments'] : 0;


?>

<!doctype html>

<html lang="en">


<head>

    <meta charset="utf-8">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Lab 01 - Final Grade Calculator</title>

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">

</head>


<body>

    <div class="container">

        <h1 class="mt-5">Final Grade Calculator</h1>

        <p>Welcome to the Final Grade Calculator!</p>

        <div class="alert alert-info mb-5">

            <h2 class="form-text fs-4 mb-4">To get started, please enter the number of assignments that you've completed so far.</h2>

            <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">

                <fieldset>

                    <div class="mb-3">

                        <label for="numassignments" class="form-label">Number of Assignments:</label>

                        <input type="number" class="form-control" name="numassignments" id="numassignments" min="1" max="10" value="<?php echo $numassignments ?>" required>

                    </div>

                    <p class="form-text">How many assignments have you already completed in this course?</p>

                </fieldset>

                <div class="mb-3">

                    <input type="submit" name="submit" value="Generate Rows" class="btn btn-primary">

                </div>

            </form>

        </div>


Enter the input value and hit 'Generate Row' to produce the input rows in the second form field. For me, I put 3.


<!-- Second form -->

        <?php if (isset($_GET['numassignments']) && $_GET['numassignments'] > 0) : ?>

            <div class="alert alert-info mb-5">

                <h2 class="form-text fs-4 mb-4">Next, for each assignment, add the grade that you received and the assignment's overall weight.</h2>

                <!-- PHP_SELF is the name of the current file WITHOUT any query string info. To retain the query string info, we can use REQUEST_URI -->

                <form action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post">

                    <fieldset>

                        <?php


                        $desired = isset($_POST["desired"]) ? $_POST["desired"] : 0;


                        for ($i = 1; $i <= $numassignments; $i++) {

                            echo "<div class=\"row\">";

                            echo "\n<div class=\"col-md-6\">"; //grade input

                            echo "\n<div class=\"mb-3\">";

                            echo "\n<label for=\"keep-numassignments{$i}\" class=\"form-label\">Assignment " . $i . " Grade:</label>";

                            echo "\n<input type=\"number\" class=\"form-control\" name=\"keep-numassignments[$i]\" id=\"keep-numassignments{$i}\" min=\"0\" max=\"100\" value=\"$keep_numassignments\" required>";

                            echo "\n</div>";

                            echo "\n</div>";

                            echo "\n<div class=\"col-md-6\">"; //weight input

                            echo "\n<div class=\"mb-3\">";

                            echo "\n<label for=\"weightnum{$i}\" class=\"form-label\">Assignment " . $i . " Weight:</label>";

                            echo "\n<input type=\"number\" class=\"form-control\" name=\"weightnum[$i]\" id=\"weightnum{$i}\" min=\"1\" max=\"100\" value=\"$weightnum\" required>";

                            echo "\n</div>";

                            echo "\n</div>";

                            echo "\n</div>";

                        }

                        ?>

                        <p class="form-text">Finally, if you would like to calculate what you will need to get on the remainder of your coursework in order to receive a certain grade, enter your desired grade below.</p>

                        <div class="mb-3">

                            <label for="desired" class="form-label">Desired Final Grade (Optional):</label>

                            <input type="number" class="form-control" name="desired" id="desired" min="0" max="100" value="<?php echo $desired; ?>">

                        </div>

                    </fieldset>

                    <div class="mb-3">

                        <input type="submit" name="gradesubmit" value="Calculate Grade" class="btn btn-primary">

                    </div>

                </form>

            </div>

        <?php endif; ?>


        <?php


        if (isset($_POST['gradesubmit'])) {

            // Retrieve the values from the form

            $grades = isset($_POST["keep-numassignments"]) ? $_POST["keep-numassignments"] : [];

            $weights = isset($_POST["weightnum"]) ? $_POST["weightnum"] : [];


            $desired = isset($_POST["desired"]) ? $_POST["desired"] : 0;


            // Calculate the weighted average of completed assignments

            $weightedSum = 0;

            $totalWeight = 0;


            for ($i = 0; $i < count($grades); $i++) {

                $weightedSum += ($weights[$i] * $grades[$i]);

                $totalWeight += $weights[$i];

            }


            $currentAverage = ($totalWeight > 0) ? ($weightedSum / $totalWeight) : 0;


            // Calculate the required grade on remaining assessments

            if ($totalWeight < 100 && $desired > 0) {

                $remainingWeight = 100 - $totalWeight;

                $requiredGrade = ($desired - (1 - ($remainingWeight / 100)) * $currentAverage) / $remainingWeight;

            } else {

                $requiredGrade = 0;

            }


            // Display the results

            echo "<div class=\"alert alert-success mb-5\">";

            echo "\n<p>Current Class Average: " . number_format($currentAverage, 2) . "%</p>";

            if ($desired > 0) {

                echo "\n<p>Required Grade on Remaining Assessments: " . number_format($requiredGrade, 2) . "%</p>";

            }

            echo "\n</div>";

        }


        ?>

    </div>


</body>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>


</html>

enter image description here



I put the input value like in the picture, but the wrong value was output. If it had been calculated correctly, the output would be produced 61.67% for the Current Class Average and 135% for the Required Grade on Remaining Assessments.


Solution

I think you mixed up the list indices for numassignments when you added items and when you read items.


When you're adding items to the list you start at 1


for ($i = 1; $i <= $numassignments; $i++)

When you're reading items from the list you start at 0


$grades = isset($_POST["keep-numassignments"]) ? $_POST["keep-numassignments"] : [];

for ($i = 0; $i < count($grades); $i++) {

                $weightedSum += ($weights[$i] * $grades[$i]);

                $totalWeight += $weights[$i];

            }



If you check the average of your first two items (50, 65) you get the average of 57.5% that you're seeing in your output.


To fix this, I would start reading your grades and weights starting from index 1 just like when you added them.


for ($i = 1; $i <= count($grades); $i++) {

                $weightedSum += ($weights[$i] * $grades[$i]);

                $totalWeight += $weights[$i];

            }


Answered by: >Jesse Sealand

Credit: >StackOverflow


Blog links: >What makes Python 'flow' with HTML nicely as compared to PHP?

>How to do wild grouping of friends in Python?

>What to do when MQTT terminates an infinite loop while subscribing to a topic in Python?

>What makes Python 'flow' with HTML nicely as compared to PHP?

>How to do Web Scraping with Python?


Ritu Singh

Ritu Singh

Submit
0 Answers