Hi, I'm trying to create a php GPA Calculator. I can't seem to get this code to work :/ <?php $multGradeAndUnit = 0; $totalUnits = 0; $fGPA; $units = 0; for($i=0; $i<7; $i++) { //these are just the names in input name = "", can rename yo anything you want $courseName = 'course'.$i; $courseUnits = 'units'.$i; $courseGrade = 'coursegrade'.$i; //we are using post to retrieve these form input variables $courseGrade = $POST[$coursegrade]; $units = $POST[$courseUnits]; $course = $POST[$courseName]; if ($courseUnits == "" && $courseGrade == "") { $multGradeAndUnit = $courseUnits * $courseGrade; $totalUnits = $courseUnits + $totalUnits; } } $fGPA = $multGradeAndUnit / $totalUnits; echo "Your GPA is: ". $fGPA ?> PHP:
$_POST? instead of $POST? And please next time provide more information about what's not working, and if possible give more code (like the HTML part)
Eric is mostly right. You need an underscore before your POST variable but the parameters need to be in single quotes, not a variable name. $courseGrade = $_POST['coursegrade']; $units = $_POST['courseUnits']; $course = $_POST['courseName']; PHP:
Would you agree it is better practice to save the double quotes for echo'ed HTML to avoid escaping characters?
absolutely, but your comment was related to variables versus a name. In this case the OP has 7 sets of questions. Rather than repeat the names of the variables 7 times s/he has a loop going. Looks like good practice to me.
Hi guys, sorry :/ Here is the index.html file, I was advised to use php arrays in getting the inputs from the form, i just don't know how will i do it :S <form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>" target="_self"> <div class="row"> <div class="large-4 columns"> <label>Course Name</label> <input type="text" placeholder="Course Code" name="course$i" id="course1"> </div> <div class="large-4 columns"> <label>Units</label> <input type="text" placeholder="No. of Units" name="units$i" id="units1"> </div> <div class="large-4 columns"> <div class="row collapse"> <label>Grade</label> <div class="small-9 columns"> <input type="text" placeholder="Grade" name="coursegrade$i" id="coursegrade1"> </div> <div class="small-3 columns"> </div> </div> </div> </div> <div class="row"> <div class="large-4 columns"> <input type="text" placeholder="Course Code" id="course2"> </div> <div class="large-4 columns"> <input type="text" placeholder="No. of Units" id="units2"> </div> <div class="large-4 columns"> <div class="row collapse"> <div class="small-9 columns"> <input type="text" placeholder="Grade" id="coursegrade2"> </div> <div class="small-3 columns"> </div> </div> </div> </div> HTML:
There's a LOT in this code that raises warning flags of broken or just sloppy methodologies. Extra variables for nothing, vague/meaningless presentational use of classes with pointless DIV for nothing, incomplete form, attributes like TARGET that have no business on any website written after 1997, false simplicity with that stupid malfing HTML 5 placeholder garbage (that are redundant to your LABELs), etc, etc, etc... Even the logic disconnect on this: if ($courseUnits == "" && $courseGrade == "") { $multGradeAndUnit = $courseUnits * $courseGrade; $totalUnits = $courseUnits + $totalUnits; } Code (markup): You're only calculating values when they are EMPTY?!? That doesn't make any sense... First order of business is to clean up the markup. The big trick is to, as you said someone else suggested, is using arrays. To do that, you just put brackets in your markup names. I would index them off a single parent to make it easier to work with. So for your three fields, they'd go something like this: name="course[1][name]" name="course[1][units]" name="course[1][grade]" Updating that number for each fieldset (and I'd be grouping each 'course' info by fieldset, NOT DIV!) On the PHP side, that will give you an array like this to work with: $_POST['course'] [ [1] => [ [name] => [units] => [grade] => ], [2] => [ [name] => [units] => [grade] => ] ]; Code (markup): Which you can then simply foreach to add together. To generate that I'd make a function to use as a template so you can pass it an action and how many 'courses' to show. I'd put it in it's own file so you can call it separately from the actual form handler -- since it appears you want to make this self calling doing so lets us avoid loading code you might not actually be running. gradeForm.php <?php function gradeForm($action,$courseCount) { echo ' <form action="',$action,'" method="post" id="gradeForm">'; for ($t = 1; $t < $courseCount; $t++) { $idBase = 'course_'.$t.'_'; $cBase = 'course['.$t.']'; echo ' <fieldset> <label for="',($id = $idBase.'Name'),'">Course Name</label> <input type="text" name="',$cBase,'[name]" id="',$id,'" /> <br /> <label for="',($id = $idBase.'Units'),'"># of Units</label> <input type="text" name="',$cBase,'[units]" id="',$id,'" /> <br /> <label for="',($id = $idBase.'Grade'),'">Grade</label> <input type="text" name="',$cBase,'[grade]" id="',$id,'" /> </fieldset>'; } echo ' <div class="submitsAndHiddens"> <input type="submit" value="Calculate GPA" /> <input type="hidden" name="fromForm" value="gradeForm" /> <!-- .submitsAndHiddens --></div> </form>'; } ?> Code (markup): Pre-building values used repeatedly and saving string additions that are used more than once inline in the output reduces the code and speeds things up a wee bit. I really don't think your math/logic for adding them up makes any sense, shouldn't multGradeAndUnit be adding together the multiplier, since you want the value at the end, not for each and every course? I'd also put this into it's own function in it's own file: gradeCalc.php <?php functon gradeCalc() { // technically there is no A+, treat as A should some dipshit type it in. $gpLookup = [ 'A+' => 4.0, 'A' => 4.0, 'A-' => 3.7, 'B+' => 3.33, 'B' => 3.0, 'B-' => 2.7, 'C+' => 2.3, 'C' => 2.0, 'C-' => 1.7, 'D+' => 1.3, 'D' => 1.0, 'D-' => 0.7 ]; $sumGradeTimesUnits = 0; $totalUnits = 0; foreach ($_POST['course'] as $course) { if ( !empty($course['units']) && !empty($course['grade']) ) { if (is_numeric($course['grade'])) { $grade = ($course['grade'] <= 4) ? $course['grade'] : 0; } else { $grade = ( isset($gpLookup[$index = strtoupper($course['grade'])]) ? $gpLookup[$index] : 0 ); } $totalUnits += $course['units']; $sumGradeTimesUnits += $course['units'] * $grade; } } if ($totalUnits > 0) { echo ' <p> Your GPA is: ',number_format($sumGradeTimesUnits / $totalUnits, 2),' </p>'; } else { echo ' <p> <strong>You failed to enter any courses!</strong> </p>'; } echo ' <a href="test.php">Click here to enter another set of courses</a>'; } ?> Code (markup): You might be wondering why I wrap these in functions -- it helps keep their vars out of the global namespace, and means if you call their files directly they don't output anything. Security 101 in scripting languages, any file the user shouldn't call directly shouldn't blindly start outputting values or running code. Functions and classes help prevent that. A demo test.php would go something like this: <?php require_once('template.php'); template_header('GPA Calculator'); if ( isset($_POST['fromForm']) && ($_POST['fromForm'] == 'gradeForm') && isset($_POST['course']) ) { require_once('gradeCalc.php'); gradeCalc(); } else { require_once('gradeForm.php'); gradeForm('test.php',7); } template_footer(); ?> Code (markup): I tossed a live copy up on my server here: http://www.cutcodedown.com/for_others/jesse27/test.php As with all my examples the directory: http://www.cutcodedown.com/for_others/jesse27/ ... is wide open for easy access to the gooey bits and pieces. I've added .phps files for direct viewing of the source, and a .rar of the entire working code. Hope this helps.
Oh, forgot to mention, I added the ability to enter either the grade points for the class, or a letter grade. A better version would have form validation too. Also, I use php 5.4 style arrays, so the above won't run on php 5.3/lower. I'm dropping support for 5.3- as there's just too much nice stuff in 5.4 for me to continue to bend over backwards supporting versions of PHP that hosts shouldn't even have installed. [] arrays, ?:, and a host of other things are just too cool not to use. ... and I'm REALLY close to going 5.5 only. array_column much?