User Tools

Site Tools


2019-07-23

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
2019-07-23 [2019/07/23 14:56]
nmckillop go go gadget colour syntax highlighting
2019-07-23 [2019/07/23 16:30] (current)
nmckillop
Line 5: Line 5:
 ==== Scratch Notes ==== ==== Scratch Notes ====
 Adding this to the top of your programs will force errors to be displayed (as opposed to hiding them from general users). ​ It might help find the source of your problem if you get an 'Error 500'. Adding this to the top of your programs will force errors to be displayed (as opposed to hiding them from general users). ​ It might help find the source of your problem if you get an 'Error 500'.
-<​code>​+<​code ​php>
 error_reporting(E_ALL);​ error_reporting(E_ALL);​
 ini_set("​display_errors",​ 1); ini_set("​display_errors",​ 1);
Line 208: Line 208:
 $json_data = file_get_contents("​http://​YOUR_IP_ADDRESS/​export.php"​);​ $json_data = file_get_contents("​http://​YOUR_IP_ADDRESS/​export.php"​);​
 $questions = json_decode($json_data,​ true); $questions = json_decode($json_data,​ true);
 +</​code>​
 +
 +==== Extra tasks  ====
 +
 +I've decided to try and separate out the complete beginners from the ones who've already got their server set up etc.  Going forward I'm going to try and put 'Level 0' or 'Level 1' on the titles of events. ​ You can read up on this on the [[lesson levels|Lesson Levels page]].
 +
 +
 +So until that is done, for those of you who are waiting while I'm setting others up, try the following:
 +
 +  * Ask someone else for their IP and see if you can load their questions into your quiz
 +  * Checkout The Moonwalk problem below
 +  * [[working_with_rss|Working with RSS]] - I made some brief notes on RSS and how to access it with PHP
 +
 +==== The Moonwalk ====
 +
 +=== Prep ===
 +Before we begin, let's get your quiz to focus just on this question while we test it (so it does't choose them at random).
 +
 +Add the question if you don't have it already, then find the ID of the question by looking at your database. ​ Then add a new line after the if statement that assigns the random number (around line 14 depending if you've made changes, just make sure it's not inside the if statement) that reads (replace 4 with your Micheal Jackson question ID):
 +
 +<code php>​$random_number = 4;</​code>​
 +
 +Remember to take this line out when you want to go back to random selection.
 +
 +Now your quiz will continually ask this question while we test some changes.
 +
 +=== Case sensitive ===
 +
 +One of my example question/​answers is "Which dance move, in which the dancer moves backwards, was made popular by Michael Jackson?",​ if someone enters all lower case '​moonwalk'​ it'll by wrong. ​ Why?  Because the "​=="​ comparison is exact (i.e. case sensitive).
 +
 +We could fix that by changing the <code php>​if($user_answer == $questions[$question_id]['​answer'​]) {</​code>​ line to use the strcasecmp() function. ​ You can read about that function here:
 +
 +https://​www.php.net/​manual/​en/​function.strcasecmp.php
 +
 +It compares one string to another, ignoring case and returns 0 if they match. ​ So, this would work:
 +
 +<code php>​if(strcasecmp($user_answer,​$questions[$question_id]['​answer'​]) == 0) {</​code>​
 +
 +This '​equals 0' thing might be a little confusing, especially if we go back to this code after a couple weeks. ​ So maybe we could try an alternative approach that is a little easier to read.  We could also use the strtolower() function and convert the user's answer (and our answer) to lower case, then use the old comparision,​ something like:
 +
 +<code php>​if(strtolower($user_answer) == strtolower($questions[$question_id]['​answer'​])) {</​code>​
 +
 +That should also work.  Whichever you use is up to what you prefer (or how you might use the answers later).  ​
 +
 +=== The '​the'​ problem ===
 +
 +For example, if I give "The Moonwalk"​ as an answer, it'll be wrong. ​ Why?
 +
 +Now, let's look at the line that checks if it matches an answer:
 +
 +<code php>​if($user_answer == $questions[$question_id]['​answer'​]) {</​code>​
 +
 +Using "​=="​ we asked it "Does the user's answer exactly match the answer in the database?",​ because "The Moonwalk"​ isn't "​Moonwalk"​ it fails (incorrect).
 +
 +Instead we could ask "Does the user's answer contain the same word we have as the answer in the database?",​ in which case "The Moonwalk"​ would contain it.
 +
 +So how do we do that?  PHP doesn'​t have a function that does exactly that, but it does have a function that tells us which character a certain string starts at.  strpos(). ​ You can read it's manual entry here:
 +
 +https://​www.php.net/​manual/​en/​function.strpos.php
 +
 +So, if we use that function, we should flip the question to be: "Does the questions'​s answer appear in the text the user has submitted?"​
 +
 +Can you get it working? ​ We'd have to do something like this:
 +
 +<​code>​if(strpos($user_answer,​ $questions[$question_id]['​answer'​]) !== false) {</​code>​
 +
 +This is a bit more complex, but it's quite a common use of strpos. ​ It's saying "Does the database answer appear in the user's answer?"​ and because of the way strpos works (it returns false if not found) we check to make sure it's not false.
 +
 +We use a special operator "​!=="​ here rather than the "​!="​ operator because it's possible strpos will return "​0"​ i.e. "Yes, I found the string you are searching for and it's at the 0th character"​ - so we want to compare the type of variable that is return (i.e. true/false) rather than assume 0 is false and 1 is true in this particular case.  Don't worry about this too much, it's not too common outside of this particular use case.
 +
 +Lastly, we'll also make it not case-sensitive,​ so the final line you should use is:
 +
 +<code php>​if(strpos(strotolower($user_answer),​ strtolower($questions[$question_id]['​answer'​])) !== false) {</​code>​
 +
 +You might want to break that into a few lines to make it easier to read/​understand later:
 +
 +<code php>
 +$AnswerUser = strtolower($user_answer);​
 +$AnswerDb = strtolower($questions[$question_id]['​answer'​]);​
 +
 +if(strpos($AnswerUser,​ $AnswerDb) !== false) {
 +</​code>​
 +
 +
 +==== Functions ====
 +How do I know which function to use?  It's basically a case of reading the manual. ​ I know we are working with strings of characters (the answers), so I look at the index of string functions:
 +
 +https://​www.php.net/​manual/​en/​ref.strings.php
 +
 +We're doing a comparison, so I just searched (CTRL + F) the list for comparison functions. ​ There are a few choices, but most are overkill, so I picked the simplest one.  Same for case sensitive functions, I searched for '​case'​ and picked something simple and appropriate.
 +
 +If we were working with numbers (and doing something more complex than equal to or less than etc), we'd want to look at the math functions:
 +
 +https://​www.php.net/​manual/​en/​ref.math.php
 +
 +
 +==== Troubleshooting ====
 +----
 +I get this error on the page sometimes: ''​Notice:​ Undefined offset: 4 in /​var/​www/​starflyer/​html/​tmp/​coding/​quiz.php on line 49''​
 +
 +You've encountered the bug on line 14.  The size of the question array is 4, but it contains elements indexed 0 to 3.  So if we use the rand() function it needs to be picking a number from 0 to the size of the array minus 1 (so it returns at most 3, not 4).  Change the random number line (14) to:
 +
 +<code php>​$random_number = rand(0, $size_of_question_list-1);</​code>​
 +----
 +I can't log into Adminer (or I'm getting access denied errors). ​ Make sure the were set properly (there was a mistake on the instructions on the wiki). ​ Log into your server and run this to reset your password:
 +
 +  * Connect to the database as the root (admin) user:
 +
 +  sudo mysql -u root
 +
 +  * Then, inside the mysql client, we created the database and created a user called ‘coding_username’,​ with the password ‘cheese’ and gave it access to the newly created ‘coding’ database:
 +
 +  create database coding;
 +  grant all on coding.* to coding_username@localhost identified by '​cheese';​
 +  quit
 +
 +Then use these details:
 +| username | coding_username |
 +| database | coding |
 +| password | cheese |
 +| host | localhost |
 +
 +----
 +My page is blank.
 +
 +Make sure you have error reporting turned on.  Add these lines to the very top of your page (after the ''<?''​):​
 +
 +<code php>
 +error_reporting(E_ALL);​
 +ini_set("​display_errors",​ 1);
 </​code>​ </​code>​
  
Line 217: Line 347:
   - Abhishek Singh   - Abhishek Singh
   - Alan Kennedy   - Alan Kennedy
-  - Allan Mullen+  - [[https://​glasgow.social/​@Angelina|Angelina Blyth]]
   - Araceli Pérez   - Araceli Pérez
   - Ayse Busra Parnell   - Ayse Busra Parnell
   - Casian Florin Dănilă   - Casian Florin Dănilă
   - Chris Cavani   - Chris Cavani
 +  - Connor Stewart
   - Donald   - Donald
   - [[https://​glasgow.social/​@Legomancer|Ed]]   - [[https://​glasgow.social/​@Legomancer|Ed]]
 +  - Erika Anderson
   - Ewan Miller   - Ewan Miller
   - [[https://​glasgow.social/​@garethk|Gareth King]]   - [[https://​glasgow.social/​@garethk|Gareth King]]
Line 233: Line 365:
   - MaryF   - MaryF
   - [[https://​glasgow.social/​@neil|Neil McKillop]] (Event Organiser)   - [[https://​glasgow.social/​@neil|Neil McKillop]] (Event Organiser)
-  - Rameez 
   - Revathi Lalam   - Revathi Lalam
   - [[https://​glasgow.social/​@M|Steven]]   - [[https://​glasgow.social/​@M|Steven]]
2019-07-23.1563893795.txt.gz · Last modified: 2019/07/23 14:56 by nmckillop