User Tools

Site Tools


2019-07-23

Differences

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

Link to this comparison view

Next revision
Previous revision
2019-07-23 [2019/07/23 08:49]
nmckillop created
2019-07-23 [2019/07/23 16:30] (current)
nmckillop
Line 1: Line 1:
-====== Meeting Notes: Tue 9th July 2019 ======+====== Meeting Notes: Tue 23rd July 2019 ======
  
-Welcome! ​ This is the notes page for our third learn-to-code-from-scratch meeting in McPhabbs (downstairs).  The plan is to run something like this every two weeks to get people up and running with basic web development and system admin.+Welcome! ​ This is the notes page for our **fourth** ​learn-to-code-from-scratch meeting in The Avalon, Kent Road.  The plan is to run something like this every two weeks to get people up and running with basic web development and system admin.
  
 ==== 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 34: Line 34:
 First, the questions. ​ Create a file called ''​questions.php''​ and enter something like this: First, the questions. ​ Create a file called ''​questions.php''​ and enter something like this:
  
-<​code>​+<​code ​php>
  
 <?php <?php
Line 57: Line 57:
 Now, a basic page to choose a question at random, and wait for the answer, let's call it ''​quiz.php'':​ Now, a basic page to choose a question at random, and wait for the answer, let's call it ''​quiz.php'':​
  
-<​code>​+<​code ​php>
  
 <?php <?php
Line 124: Line 124:
  
 A quick way to create the table in Adminer is to copy and paste this SQL into the **SQL Command** section: A quick way to create the table in Adminer is to copy and paste this SQL into the **SQL Command** section:
-<​code>​+<​code ​sql>
 CREATE TABLE `quiz_questions` ( CREATE TABLE `quiz_questions` (
   `question_id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,   `question_id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
Line 137: Line 137:
 And now, this SQL will add some test questions to it (or you can enter some yourself by clicking on the newly created "​quiz_questions"​ table and clicking 'New Item'​):​ And now, this SQL will add some test questions to it (or you can enter some yourself by clicking on the newly created "​quiz_questions"​ table and clicking 'New Item'​):​
  
-<​code>​+<​code ​sql>
 INSERT INTO `quiz_questions` (`question`,​ `answer`, `last_asked`) INSERT INTO `quiz_questions` (`question`,​ `answer`, `last_asked`)
 VALUES ('What was originally considered to be the ninth planet from the Sun but after 1992 had its status as a large planet changed?',​ '​Pluto',​ now()); VALUES ('What was originally considered to be the ninth planet from the Sun but after 1992 had its status as a large planet changed?',​ '​Pluto',​ now());
Line 151: Line 151:
 Let's create a new file, this one called ''​questions_from_db.php''​ - we'll be using some code from the [[2019-04-06|connecting to your DB sample]]: Let's create a new file, this one called ''​questions_from_db.php''​ - we'll be using some code from the [[2019-04-06|connecting to your DB sample]]:
  
-<​code>​+<​code ​php>
 <?​php ​ <?​php ​
  
Line 178: Line 178:
 ==== Putting it all together ==== ==== Putting it all together ====
 Now, if everything has went to plan, you can replace the: Now, if everything has went to plan, you can replace the:
-<​code>​require("​questions.php"​)</​code>​+<​code ​php>​require("​questions.php"​)</​code>​
  
 line from your ''​quiz.php''​ file with: line from your ''​quiz.php''​ file with:
-<​code>​require("​questions_from_db.php"​)</​code>​+<​code ​php>​require("​questions_from_db.php"​)</​code>​
  
 and now, when you enter new questions to the database, they'​ll be available in your quiz. and now, when you enter new questions to the database, they'​ll be available in your quiz.
Line 191: Line 191:
 You can make your questions, in your database, available to anyone else's quiz program with this bit of code, call it ''​export.php'':​ You can make your questions, in your database, available to anyone else's quiz program with this bit of code, call it ''​export.php'':​
  
-<​code>​+<​code ​php>
 <?php <?php
 header("​Content-Type:​ application/​json"​);​ header("​Content-Type:​ application/​json"​);​
Line 205: Line 205:
  
 This code will connect to a fellow coder'​s IP address, download their quiz questions and format them in a way your program can understand them: This code will connect to a fellow coder'​s IP address, download their quiz questions and format them in a way your program can understand them:
-<​code>​+<​code ​php>
 $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
-  - Scott Carlile 
   - [[https://​glasgow.social/​@M|Steven]]   - [[https://​glasgow.social/​@M|Steven]]
   - Tapan Parida   - Tapan Parida
2019-07-23.1563871743.txt.gz · Last modified: 2019/07/23 08:49 by nmckillop