how to make simple PHP base quiz - php

I want to make 15 questions, and any time user visits the page it shows random 5 questions and each question has 4 answers and 1 is the correct. The marks are 20, 15, 10 and 0.
How can i make it?

I always find it best to start learning by Googling for tutorials.
Here are a few:
simple php quiz
select random list items in php
I'm sorry to tell you go Googling, but I think the tutorials and examples you'll find there, will be far more helpful to you than any answer here on StackOverflow.

Ok well nobody is going to write the full code for you I think, but as a general schema design, you'd want something like this...
questions table (q_id, q_question)
questionoptions (qo_optionid, qo_questionid, qa_option)
useranswers (ua_userid, ua_questionid, ua_optionid)
To get the choices for a given question (question 1 lets say)
select
*
from
questions
inner join questionoptions on (qo_questionid = q_id)
order by
qo_optionid
To get a report of the options each user chose...
select
*
from
questions
inner join questionoptions on (qo_questionid = q_id)
inner join useranswers on (ua_questionid = q_id and ua_optionid = qo_optionid)
order by
ua_userid, ua_questionid
Note that im not advocating the use of SELECT *, but its there for simplicity of example.

Related

select statement retrieving data from 2 tables

I have a list of clickable questions from which I'm looking to open in a new page and also display a list of options to select from a bit like a quiz or test.
So lets say in the database TableQuestions has the questions saved and TableAnswers has the possible options saved. The Answers table also includes the ID from the Questions table to determine what options are associated with each question.
However when I click the on a question it is displaying all the questions and all the answers from the database where I just want to display the question that I have clicked and the answers which have the same ID as the question.
This is my SELECT statement:
("SELECT tableQuestions.*, tableAnswers.* FROM tableQuestions, tableAnswers WHERE tableQuestions.question_id=tableAnswers.question_id");
Can anyone assist with this?
Thanks
Seems like you forgot to add the Id of clicked question in the SQL, so you get all questions.
Also, what you do here (brining data from 2 tables) is called joining tables, and the better syntax for this is with JOIN ... ON in the FROM part.
SELECT tableQuestions.*, tableAnswers.* FROM tableQuestions INNER JOIN tableAnswers
ON tableQuestions.question_id=tableAnswers.question_id
WHERE tableQuestions.question_id = <id>
As addition to Yossi's answer: You should use LEFT JOIN, insdead of INNER JOIN. This will allow you to display the questions which don't have answers.

Large Dataset Cron Job Suggestions

I have an interesting situation of calculations that need to be made in a project, and am looking for an efficient way to handle it. Here is the scenario.
We are making a "Polling" website, where users answer Poll questions. They can answer each question once.
We are generating a "Score" for every user based on their answers. They receive 1 point for each other user that answered the same.
For Example:
Question 1 has 2 answers, "Yes" and "No"
7 Users answered "Yes" and 3 answered "No"
Each User that answered "Yes" adds 7 points to their score
Each User that answered "No" adds 3 points to their score
If a 4th User answers "No", 1 extra point is added to each User that answered "No"
As you can imagine, it would be far too many calculations to do this on the fly, since lots of user scores must be regenerated every time a question is answered. So I want to do this as a Cron Job every X hours.
My Data currently returns a single Row for each Question answered by a single user, along with how many points each answer is worth (comma separated: 7,3)
How should I go about regenerating these results? I do not want to use a simple "Foreach" to loop through every User, as this doesn't seem like it will scale as the User base grows. Is there a way to run PHP scripts in the background or concurrently, as to not cause the loop to hang?
Any help or suggestions are greatly appreciated!
EDIT:
Sorry, I should have explained the database a bit too.
This is a WordPress website, so some of the data is in the default WordPress postmeta table. The tally is stored as comma separated meta_key value for the "Post" (Poll question)
All answers are store in their own answers table. Each answer is a row in the table, and it includes user_id, post_id (of poll question), answer chosen(index of comma separated meta_key value)
And this is the query I am using to get all the answers for a particular User:
SELECT * FROM `wp_myo_ip` LEFT JOIN `wp_postmeta` ON `wp_myo_ip`.`myo_polling_id` = `wp_postmeta`.`post_id` AND `wp_postmeta`.`meta_key` = 'myo-votes' WHERE `wp_myo_ip`.`myo_polling_ip` = 1
The myo_polling_ip column is actually the User ID
Based on absolutly no database information given ...
UPDATE answer_tbl
LEFT JOIN (SELECT answer_tbl.id, IF(answer_tbl.answer = 'YES', COUNT(yes_tbl.id), COUNT(no_tbl.id)) AS score
FROM answer_tbl
LEFT JOIN answer_tbl AS yes_tbl ON answer_tbl.question_id = yes_tbl.question_id AND yes_tbl.answer = 'YES'
LEFT JOIN answer_tbl AS no_tbl ON answer_tbl.question_id = no_tbl.question_id AND no_tbl.answer = 'NO'
WHERE 1
GROUP BY answer_tbl.id) AS score_tbl
SET answer_tbl.score AS score_tbl.score
WHERE answer_tbl.id = score_tbl.score

MCQ quiz is slow to load and randomization does not work

I am creating a MCQ quiz based on php and mysql. Here are the structures of my main tables:
quiz table: quiz id, quiz_category
category table: id, title...
questions table: id, quiz id, categoryid, title...
answers table: id, question id...
To start things, I have the tables populated with 150+ quizzes, 4 categories, 14000+ questions and rightanswers for each.
To save time, for each question, the right answer is pulled from the answers table https://stackoverflow.com/editing-helpalongwith 3 other random answers .
Now when I was testing it with just two quizzes, it worked fine. But with 150 quizzes, several problems have cropped up:
the database is slow and for later quizzes takes forever to load questions
the randomization of answers is not working anymore - along with the right answer, the other options show the same entry, making it easy for the user to guess the right answer.
You can see the code I am working with in my previous Stackoverflow query. https://stackoverflow.com/questions/14826573/randomising-questions-and-answers-php-quiz-not-working
Any idea about what the ideal queries should be for the quiz program to work?
I will provide some tips on how to improve performance, however these will be generic and may not be complete.
From briefly looking at your PHP and SQL statements from your previous question, there are a few logical places for an index. To add an index please reefer to the MySQL manual for more information
$sql4="select * from answers where question_id=".$row2['id'];
question_id should have an index
$sql2="select * from questions where quiz_id=".$_SESSION['quizid'];
quiz_id should have an index
Adding these two indexes will also improve selectivity on this
$sql3="select * from answers where question_id in (select id from
questions where quiz_id =$row2[quiz_id]) order by rand()";
This will help as previously you would have been performing a full table scan for each query.
Your other issue is that you have a loop and on each iteration you are sending commands to query the database, you should collect all the information at once before the loop and then iterate using that rather than sending individual queries each iteration.

Choosing data pseudo-randomly with even distribution

I'm currently working on a medium-sized web project, and I've ran into a problem.
What I want to do is display a question, together with an image. I have a (global) list of questions, and a (global) list of images, all questions should be asked for all images.
As far as the user can see the question and image should be chosen at random. However the statistics from the answers (question/image-pair) will be used for research purposes. This means that all the question/image-pair must be chosen such that the answers will be distributed evenly across all question, and across all images.
A user should only be able to answer a specific question/image-pair one time.
I am using a mysql database and php. Currently, i have three database tables:
tbl_images (image_id)
tbl_questions (question_id)
tbl_answers (answer_id, image_id, question_id, user_id)
The other columns are not related to this specific problem.
Solution 1:
Track how many times each image/question has been used (add a column in each table). Always choose the image and question that has been asked the least.
Problem:
What I'm actually interested in is distribution among questions for an image and vice versa, not that each question is even globally.
Solution 2:
Add another table, containing all question/image-pairs along with how many times it has been asked. Choose the lowest combination (first row if count column is sorted by ascending order).
Problem:
Does not enforce that the user can only answer a question once. Also does not give the appearance that the choice is random to the user.
Solution 3:
Same as #2, but store question/image/user_id in table.
Problem:
Performance issues (?), a lot of space wasted for each user. There will probably be semi-large amounts of data (thousands of questions/images and atleast hundreds of users).
Solution 4:
Choose a question and image at true random from all available. With a large enough amount of answers they will be distributed evenly.
Problem:
If i add a new question or image they will not get more answers than the others and therefore never catch up. I want an even amount of statistics for all question/image-pairs.
Solution 5:
Weighted random. Choose a number of question/image pairs (say about 10-100) at true random and pick the best (as in, lowest global count) of these that the user has not answered.
Problem:
Does not guarantee that a recently added question or image gets a lot of answers quickly.
Solution #5 is probably the best once I've come up with so far.
Your input is very much appreciated, thank you for your time.
From what I understand of your problem, I would go with #1. However, you do not need a new column. I would create an SQL View instead becuase it sounds like you'll need to report on things like that anyway. A view is basically a cached select, but acts similar to a table. Thus you would create a view for keeping the total of each question answered for each image:
DROP VIEW IF EXISTS "main"."view_image_question_count";
CREATE VIEW "view_image_question_count" AS
SELECT a.image_id, a.question_id, SUM(b.question_id) as "total"
FROM answer AS a
INNER JOIN answer AS b ON a.question_id = b.question_id
GROUP BY a.image_id, a.question_id;
Then, you need a quick and easy way to get the next best image/question combo to ask:
DROP VIEW IF EXISTS "main"."view_next_best_question";
CREATE VIEW "view_next_best_question" AS
SELECT a.*, user_id
FROM view_image_question_count a
JOIN answer USING( image_id, question_id )
JOIN question USING(question_id)
JOIN image USING(image_id)
ORDER BY total ASC;
Now, if you need to report on your image to question performace, you can do so by:
SELECT * FROM view_image_question_count
If you need the next best image+question to ask for a user, you would call:
SELECT * FROM view_next_best_question WHERE user_id != {USERID} LIMIT 1
The != {USERID} part is to prevent getting a question the user has already answered. The LIMIT optimizes to only get one.
Disclaimer: There is probably a lot that could be done to optimize this. I just wanted to post something for thought.
Also, here is the database dump I used for testing. http://pastebin.com/yutyV2GU

phpBB automated email notifications to all members regarding all posts

While I search this one out on my own, may be some one could provide quick answer. Thank you so much in advance.
So i really enjoy google groups and how every member receives notification about all new things that happen in the group. All new topics, old topics, added replies and so on. But we need our own forum, so my group went with phpBB forum on our site.
I basically want my board to send out notifications to all members. So that members that are on the phone do not have to be present on the forum physically.
Any one faced this issue before, any quick solutions? Settings in phpBB that can address that right away. May be custom setting for groups?
==============================================================================
As I have found out, actually every user can subscribe to forums. Haven't been looking hard enough or just missed it. That produces desired effect for me. But so far I have no idea of a way to force that behavior for all users regardless of their actions. Which would be preferable for small board. But good news if this natively supported by phpBB i bet i can write some code to extend this feature.
The only thing I can think of is somehow forcing every member to subscriber to every applicable forum/thread. I would look to do this via a back-end query, not through anything phpBB provides.
After looking online at the phpBB schema, I propose the following query set to be run daily via a cron job:
insert into phpbb_forums_watch
select distinct f.forum_id, u.user_id, 0
from phpbb_forums f, phpbb_users u
where u.user_type = 0
and not exists (select 1 from phpbb_forums_watch
where forum_id = f.forum_id
and user_id = u.user_id);
insert into phpbb_topics_watch
select distinct t.topic_id, u.user_id, 0
from phpbb_topics t, phpbb_users u
where u.user_type = 0
and not exists (select 1 from phpbb_topics_watch
where topic_id = t.topic_id
and user_id = u.user_id);
Let me know what you think of this..
I also posted this question on phpBB forums: thats what I got -> http://www.phpbb.com/community/viewtopic.php?f=72&t=2106567&p=12877384#p12877384
there is apparently mod that is available.
thank you all for help.

Categories