PNewCode Posted February 23 Share Posted February 23 (edited) Hello everyone. I hope you're having a great day! I'm attempting to make a basic math test that gives one question, a input field to enter an answer, and if its correct then it shows the answer and an image to say they win. If in correct then still shows the answer with an image that says they didn't win. Sounds pretty basic right? I can't wrap my head around what I'm doing wrong. When I run this, then weather it's right or wrong, I just get a blank page. I've been at this for so long with different variations that I'm starting to feel fatigue haha. Any help is greatly appreciated. The file is math8.php PS I also get the follow errors which is confusing me because in my mind, these ARE defined. But I can see that the errors say their not. I'm not understanding why though.Warning: Undefined array key "number_entered" in math8.php on line 32 Warning: Undefined array key "submit" in math8.php on line 34 <?php error_reporting(E_ALL); ini_set('display_errors', '1'); $rand1 = rand(0, 9); $rand2 = rand(0, 9); $operator = array('*', '/', '+', '-'); $randoperator = $operator[rand(0, 3)]; switch ($randoperator) { case "+": $finaalvalue = $rand1 + $rand2; break; case "-": $finaalvalue = $rand1 - $rand2; break; case "*": $finaalvalue = $rand1 * $rand2; break; case "/": $finaalvalue = $rand1 / $rand2; break; echo $rand1 . $randoperator . $rand2 . '=' . $finaalvalue; } ; if(!isset($_POST['number_entered'])){ $number= $_POST['number_entered']; $submitbutton= $_POST['submit']; echo ' <form id="id" action="" method="POST"> <br><b>Level 1<br>Do The Math</b><br><br>'; echo $rand1 . $randoperator . $rand2 . '='; echo '<input type="text" name="number_entered" value="" autocomplete="off"> <br><br>'; echo ' <input class="button" type="submit" name="submit" value="Enter Guess"><br><br> </form> '; if ($submitbutton){ if ($number != $finaalvalue){ echo "Incorrect guess<br>The correct<br>number was <b>$finaalvalue</b> <br><img src='sorry-tryagain.png'><br>"; }else{ echo "<img src='you-win.png'><br><b>$finaalvalue</b> IS THE<br>CORRECT GUESS!</b><br>"; } } } ?> Edited February 23 by PNewCode Quote Link to comment https://forums.phpfreaks.com/topic/318470-php-random-math-test-with-form-entry/ Share on other sites More sharing options...
mac_gyver Posted February 23 Share Posted February 23 web servers are stateless. they don't know or care what has happened outside of the current request. each time your code runs, it generates new random values. if you want to remember these values, from one request to the next, you need to store them in session variables, and only generate new ones if the session variables are empty/not-set. Quote Link to comment https://forums.phpfreaks.com/topic/318470-php-random-math-test-with-form-entry/#findComment-1616461 Share on other sites More sharing options...
Barand Posted February 23 Share Posted February 23 You are trying to do your processing when number_entered is NOT set. if(!isset($_POST['number_entered'])){ ^ Quote Link to comment https://forums.phpfreaks.com/topic/318470-php-random-math-test-with-form-entry/#findComment-1616462 Share on other sites More sharing options...
PNewCode Posted February 23 Author Share Posted February 23 @mac_gyver and @Barand thank you for that info! I appreciate it. I think I understand what you're saying. But then again not really haha. If I'm understanding you, then it's not really working to post anything but is just recycling the page to make a new math problem? But then, it's not? Just translating in my own mind that is less skilled with less termonology haha. Okay so, is what I'm attempting to accomplish even possible then to do all in one page? The only session that I have with it is the users session (different php script that is going to be included once I get this working so I can add some database scores and etc etc) Quote Link to comment https://forums.phpfreaks.com/topic/318470-php-random-math-test-with-form-entry/#findComment-1616464 Share on other sites More sharing options...
PNewCode Posted February 24 Author Share Posted February 24 I hope I'm not stepping out of bounds on this, but is there a way I can just pay someone to make this work? If I'm out of line then I appologize. Another 5 hours have passed and I can't make heads or tails out of how to make this work. I don't need to save the answer in a database or anything like that. It's just going to be as basic as can be. A random math question shows, the user enters the answer, then it shows if it's right or wrong without showing a new math question. I feel foolish I can't find a single thing online to where I can learn what to do here. And I'm sure you both are correct in what you're saying. Unfortunately, I don't understand what you're saying Quote Link to comment https://forums.phpfreaks.com/topic/318470-php-random-math-test-with-form-entry/#findComment-1616475 Share on other sites More sharing options...
Solution mac_gyver Posted February 24 Solution Share Posted February 24 (edited) are you doing this as a learning exercise? what is your goal? some pointers - the code for any page should be laid out in this general order - 1) initialization, 2) post method form processing, 3) get method business logic - get/produce data needed to display the page, 4) html document. the post method form processing should not attempt to detect if the submit button is set, there are cases where it won't be. instead, detect if a post method form was submitted before referencing any of the form data. keep all the form data as a set, in a php array variable, then operate on elements in this array variable throughout the rest of the code. trim all the input data before validating it, mainly so that you can detect if all white-space characters were entered. validate all the trimmed input data at once, storing user/validation errors in an array, using the field name as the main array index. after the end of the validation logic, if there are no errors (the array holding the user/validation errors is empty), use the input data. since all you are doing is comparing an input value with the correct answer, you can do this as part of the validation logic. if you were storing data in a database, authenticating a user, sending an email, ... you would put the code needed to perform these actions here. after using the input data, if there are no errors, perform a redirect to the exact same URL of the current page to cause a get request for the page. this will prevent the browser from trying to resubmit the form data should the page get reloaded or browsed back to. to display a one-time success message, store it in a session variable, then test, display, and clear that session variable at the appropriate location in the html document. if there are user/validation errors, the code will continue on to display the html document, display any errors, redisplay the form, populating the field values with any existing data, so that the user doesn't need to keep reentering values over and over. any dynamic value you output in a html context needs to have htmlentities() applied to it to help prevent cross site scripting. there's a programming issue with the division operator and computers. this operation can result in a fractional part that cannot be represented exactly in a computer and then cannot be easily compared. you may want to test the answer produced is this case and limit the question/answer to those which only have whole integer answers, i.e. keep something like 9/3, but not 7/6, and also don't allow division by 0. if you do all of that, except for handling the division cases, you would end up with code that looks like this - <?php // initialization // the error related settings should be in the php.ini on your system error_reporting(E_ALL); ini_set('display_errors', '1'); session_start(); $post = []; // array to hold a trimmed working copy of the form data $errors = []; // array to hold user/validation errors // post method form processing if($_SERVER['REQUEST_METHOD'] === 'POST') { // inputs: number_entered, $_SESSION['answer'] // trim all the post data at once $post = array_map('trim',$_POST); // if any input is a array, use a recursive trim call-back function here instead of php's trim // validate inputs if($post['number_entered'] === '') { $errors['number_entered'] = 'You must enter a number'; } // note: this assumes that only integer answers are permitted (in the case of the division operator) else if((int)$post['number_entered'] !== (int)$_SESSION['answer']) { $errors['number_entered'] = "Incorrect guess<br>The correct<br>number was <b>{$_SESSION['answer']}</b> <br><img src='sorry-tryagain.png'><br>"; // since you are displaying the correct answer, you would want to generated a new question in this case? //unset($_SESSION['question']); } // if no errors, success if(empty($errors)) { $_SESSION['success_message'] = "<img src='you-win.png'><br><b>{$_SESSION['answer']}</b> IS THE<br>CORRECT GUESS!</b><br>"; // to continue, you would generated a new question //unset($_SESSION['question']); // redirect to the exact same url of the current page to cause a get request - PRG Post, Redirect, Get. die(header("Refresh:0")); } } // get method business logic - get/produce data needed to display the page // if there's no question/answer, generate one if(!isset($_SESSION['question'])) { $rand1 = rand(0, 9); $rand2 = rand(0, 9); $operator = array('*', '/', '+', '-'); $randoperator = $operator[rand(0, 3)]; switch ($randoperator) { case "+": $finaalvalue = $rand1 + $rand2; break; case "-": $finaalvalue = $rand1 - $rand2; break; case "*": $finaalvalue = $rand1 * $rand2; break; case "/": // note: this can produce a fractional number, which you must take care with when performing comparisons. // also division by zero. $finaalvalue = $rand1 / $rand2; break; } $_SESSION['question'] = "$rand1 $randoperator $rand2 = "; $_SESSION['answer'] = $finaalvalue; } // html document - this is an incomplete document. it only shows the necessary parts for the demonstration. ?> <?php // display any success message if(isset($_SESSION['success_message'])) { echo $_SESSION['success_message']; unset($_SESSION['success_message']); } ?> <?php // display any errors if(!empty($errors)) { echo "<p>".implode('<br>',$errors)."</p>"; } ?> <?php // display the form if(!empty($_SESSION['question'])) { ?> <form method="POST"> <br><b>Level 1<br>Do The Math</b><br><br> <?=$_SESSION['question']?> <input type="text" name="number_entered" value="<?=htmlentities($post['number_entered']??'',ENT_QUOTES)?>" autocomplete="off"><br><br> <input class="button" type="submit" value="Enter Guess"><br><br> </form> <?php } Edited February 24 by mac_gyver Quote Link to comment https://forums.phpfreaks.com/topic/318470-php-random-math-test-with-form-entry/#findComment-1616478 Share on other sites More sharing options...
PNewCode Posted February 24 Author Share Posted February 24 @mac_gyver To answer your question, the goal was for learning and also give my viewers a simple math question that will go along with a bunch of other trivia. Just for fun. And yes also to learn from. I'm told by most people that I know that my mind works weird. I tend to reverse engineer things to learn most. I'll take a web page and see it as a viewer to see what it does, then look at the script to see how it works, then learn and build from there. Most of the time it works for me, but then other times it doesn't. Unfortunately I have a learning handicap to where if I was to be given instructions on how to build a clock (like a literal one that is on the wall) I would be lost. But if I took a clock apart, then I can see how it's done and build another one. And then often enough I can build more to add to that clock from there. I know... I'm strange. That being said, what you posted is VERY educational to me! I simply pasted your code that you provided into a page and then uploaded it. I saw it working. Then I went back to go line by line from what you said before providing the code and learned from it while going through that code. And now it all MOSTLY makes sense to me. I confess that not all of it does but I know it will soon, as some of it is just termonology that I'm unfamiliar with. HOWEVER, it has some terms that I didn't understand 2 or 3 months ago, but now do because of this website. Overall, I understand a lot more of why it works as apposed to what I had created to begin with. Sorry this is a long post but I wanted to properly thank you by explaining exactly how it educated me. I am very greatful for that! THANK YOU! Quote Link to comment https://forums.phpfreaks.com/topic/318470-php-random-math-test-with-form-entry/#findComment-1616493 Share on other sites More sharing options...
PNewCode Posted February 24 Author Share Posted February 24 @mac_gyver I resolved the division zero issue by changing the lines rand(0, 9) to rand(1, 9) If you don't mind an extenstion on it, is there a way to not show the question and answer form after the answer is given? Right now, it shows the answer again under the CORRECT or INCORRECT display, after the answer is given. Quote Link to comment https://forums.phpfreaks.com/topic/318470-php-random-math-test-with-form-entry/#findComment-1616495 Share on other sites More sharing options...
Barand Posted February 24 Share Posted February 24 As well as chaging the rand() ranges to 1-9 I would also change the way rand1 and rand2 are used in the case of division. allocate rand1 to the finalvalue and then multiply rand1 by rand2. This avoids none integer results. IE.. rand1 * rand2 ------------- = rand1 rand2 My code for this bit would be $rand1 = rand(1, 9); $rand2 = rand(1, 9); $randoperator = rand(0, 3); $operators = array('×', '÷', '+', '−'); $finalvalue = match($randoperator) { 0 => $rand1 * $rand2, 1 => handleDivide($rand1, $rand2), 2 => $rand1 + $rand2, 3 => $rand1 - $rand2 }; $question = "$rand1 {$operators[$randoperator]} $rand2 ="; echo "$question $finalvalue<br>"; function handleDivide(&$r1, $r2) { $fv = $r1; $r1 *= $r2; return $fv; } Quote Link to comment https://forums.phpfreaks.com/topic/318470-php-random-math-test-with-form-entry/#findComment-1616516 Share on other sites More sharing options...
PNewCode Posted February 26 Author Share Posted February 26 @Barand Thank you I will try to put that in with what @mac_gyver gave too. I've been studying this a lot over the last couple days and I'm starting to understand how it all works. I'm still stuck on how to keep a new question from showing (or the current question) below the results (after the user answers it). I unset it all to get it to do a new one in case of refresh so that works but even before I did that then it would still show that question again below the results. The problem with that is that it will allow the user to answer again if they get it wrong. If they get it wrong then there's no redo, I don't want them to have the ability to put in a new answer to move forward. Quote Link to comment https://forums.phpfreaks.com/topic/318470-php-random-math-test-with-form-entry/#findComment-1616582 Share on other sites More sharing options...
Barand Posted February 26 Share Posted February 26 Like this? Code <?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { ## ## Process posted data ## $number = $_POST['number_entered'] ?? 0; $answer = $_POST['answer'] ?? 0; $question = $_POST['question'] ?? ''; $check = $number == $answer ? "<span class='w3-badge w3-green w3-xlarge'>✓</span>" : "<span class='w3-badge w3-red w3-xlarge'>×</span>"; $output = <<<OUT <span class="qtext">$question $number</span> $check <br><br> <a href='' class='w3-button w3-indigo'>Ask me another</a> OUT; } else { ## ## Ask new question ## $rand1 = rand(1, 9); $rand2 = rand(1, 9); $randoperator = rand(0, 3); $operators = array('×', '÷', '+', '−'); $finalvalue = match($randoperator) { 0 => $rand1 * $rand2, 1 => handleDivide($rand1, $rand2), 2 => $rand1 + $rand2, 3 => $rand1 - $rand2 }; $question = "$rand1 {$operators[$randoperator]} $rand2 ="; $output = <<<OUT <form method='POST'> <span class="qtext">$question</span> <input type='hidden' name='question' value='$question'> <input type='hidden' name='answer' value='$finalvalue'> <input type='number' name='number_entered' placeholder='?' autofocus> <br><br> <button class='w3-button w3-indigo'>Submit answer</button> </form> OUT; } function handleDivide(&$r1, $r2) { $fv = $r1; $r1 *= $r2; return $fv; } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Example</title> <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <style type='text/css'> div { padding: 16px; text-align: center; } input { width: 70px; text-align: center; font-size: 20pt; } .qtext { font-size: 20pt; } </style> </head> <body> <div class='w3-blue-gray'> <h1>Do the Math</h1> </div> <div> <?= $output ?> </div> </body> </html> Quote Link to comment https://forums.phpfreaks.com/topic/318470-php-random-math-test-with-form-entry/#findComment-1616595 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.