Linking questions to numbers

I'd like to make a program that resembles a pop quiz. In this program I would like to create multiple questions that is randomly generated and then displayed. Does anyone know how one might go about doing this? Here's my concept so far. (There's still some details to iron out.)

Ex:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <string>
#include <time>
#include <cstdlib>

int main()
{
  std::string q1 = "what how many atoms does Helium have?";
  std::string q2 = "What symbol is H?";
  std::string q3, q4;
  int a = 1,b = 2,c = 3,d = 4;

  //Let 1 = q1, 2 = q2, 3 = q3, 4 = q4;
  
  srand((unsigned)time(0)); 
  int i;
  i = (rand()%5)+1;

  //generate a random number, match it to a,b,c, or d and then output that question.
  cout << i << "\n";

}


Please let me know if I should clarify anything else. Thank you!

edit: Modified to make code easier to read. 11/25/18
Last edited on
looks to me like you need a custom type to hold a question and its answer(s) and maybe which answer is correct. do you know struct / class yet? If not, do you know vector or arrays? eg an array of 5 strings (question, 4 answers, and which answer is correct, or that can be 'understood' eg the first answer is always correct) and then you can spit out the question and then the answers in random order, or something along those lines.

I think you'll find it easiest to store the questions and answers in a file and have your program read and process the file. In other words, the program will read the first question, display the possible answers, prompt the user for their answer and let them know if they are right or wrong.

To do this your file must indicate when a new question starts, when the answers start, and which answer is correct.

The advantage of doing it this way is that once the program is written, you can add as many questions as you like by just editing the file.
So I'm looking at the proposed solution from jonnin and dhayden.

Yes, I know about class, vectors, array, static, dynamic arrays, as well as inheritance which is where I'm going with this.


I love the idea sharing so far and I'm considering the options. This is probably the core issue: Would you say the best method of learning is offering multiple choice answers to a question? Or inputting an answer to a question you don't know?

Ex: How many atoms does Helium have?

a) 1
b)5
c)56
d)42

or
How many atoms does Helium have?

User inputs answer.

Once I can figure out this answer I can either go forward with dhayden's method or jonnin's method.

In essence, elements have data that will never change such as the # of atoms it has, if it's a solid gas, etc.
Hello EmperorRookie,


PLEASE ALWAYS USE CODE TAGS (the <> formatting button), to the right of this box, when posting code.

It makes it easier to read your code and also easier to respond to your post.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

Hint: You can edit your post, highlight your code and press the <> formatting button.
You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.



Ex: How many atoms does Helium have?

The answer is 2. See periodic table https://www.google.com/imgres?imgurl=https://thehazmatguys.com/wp-content/uploads/2018/08/periodic-table-e1533317971576.png&imgrefurl=https://thehazmatguys.com/thmg143-periodic-table-part-1/&h=768&w=1024&tbnid=kgJQVoCThlnFnM:&q=periodic+table&tbnh=150&tbnw=200&usg=AI4_-kT1_xQolsiVQAJQL1H2A1a1KwCrUw&vet=12ahUKEwj5gfOW8ezeAhWH6oMKHfsoCKcQ_B0wEnoECAUQBg..i&docid=8bLr8vU9XsKwvM&itg=1&sa=X&ved=2ahUKEwj5gfOW8ezeAhWH6oMKHfsoCKcQ_B0wEnoECAUQBg#h=768&imgdii=kgJQVoCThlnFnM:&tbnh=150&tbnw=200&vet=12ahUKEwj5gfOW8ezeAhWH6oMKHfsoCKcQ_B0wEnoECAUQBg..i&w=1024

Once you have your questions and answers a combination of dhayden's and jonnin's ideas will work.

You are not the first with this type of program. Try searching here to see similar programs.

Hope that helps,

Andy
our methods are identical in terms of concept. I said store it in a data structure, he said use a file, but the key is storing the data all together so you can process it in your program to generate what you want. How you store it isn't really a big deal so long as you store it such that one question and its answers are easily tied together to allow you to do the work. It is a lot more flexible to use the file; then your same program will work for any quiz for any class .. chemistry or history, it won't care!
If i were the one, i will design the program like this
1) class Answer. This class has 2 data members
Type value;
bool correct.

Has getter and setter for the data members

If you know Generic programming, this class will be a template so that
Type could be any type

2. class Question. This class has 2 data members
std::string question;
std::vector<Answer> options;

This way, an Answer has a value anad knows if it is the correct answer
e.g Answer ans(2, true); //

A question knows all options and knows the correct answer from the options

You can add other responsibilities for each class e.g
an Answer can write to to file and read an Answer object from file. Same for Question.

In
1
2
3
4
5
6
7
8
9
10
11
 int main(){
vector<Answer> ans{...some...values...}
Question question ("How many planets on earth?", ans);

cout <<question << endl;  // you have overloaded << in Question

//user chooses
if(question.getAnswer() ==  "user input){
// this answer is correct
}
..... 


EDIT: More info...
If you have a vector<Question> questions then getting random number of them is as simple as randomly generating random unique n numbers and then get them from the vector with questions.at(randomPosition).

If u have them on file, then
1. read file
2. Load vector of Questions
3. Randomly get the ones to display


Hope that helps.

Last edited on
This is just one man's opinion not backed up by anything other than my own reasoning.

When I was a student I loved multiple choice tests because they very easy, weak tests of knowledge. Oftentimes the correct answer can be narrowed down to two or even one candidate because of the way multiple choice answers are structured.

Also, tests should never test luck, IMO. Multiple choice tests have a luck factor.

I recommend word answers over multiple choice. Short answer type questions would be even better, but obviously those don't work because a computer isn't smart enough to check them.
Last edited on
@Browni I agree that multiple choice provides an opportunity for luck which while may be good for your grade isn't really the reason someone goes to "learn" something (Chemistry).

Anyways, bless you guys for being friendly and taking your time to show me the various methods to accomplish this goal.

@HandyAndy I was on phone in my lunch break when I typed that so please forgive me there haha( In regards to the # of atoms helium has). Also I shall update the post to make it look good, thank you for that!

_______________________________________________________

@Blongho I will look at the code you provided me with and study it then I'll create both to see which program I like best. For the multiple choice I will follow your advice, but for the user input I will create:

Create a file with questions.
Create a file with answers.
During the question process inform the user to enter data spelled correctly.
If user inputs "HelIuM", then I tolower the input which will in turn set the answer to "helium".
Then match it up with the stored data. H =helium.
If ans == storedData then output correct, else wrong.

Ex: HelIuM to "helium".
"helium" == "helium".


I shall keep you guys posted on this. Thank you for the help guys! Hope you guys had a Happy Thanksgiving.
EmperorRookie wrote:
I agree that multiple choice provides an opportunity for luck which while may be good for your grade isn't really the reason someone goes to "learn" something (Chemistry).


Right, I don't think they're good for learning. I loved them because I was an underachiever who wanted to get to get through the day with minimal effort. For someone who is actively trying to learn I don't think they gauge progress very well.
I think multiple choice tests are more about the ease of grading than the benefits of learning. It's much easier to grade a multiple choice test.

Blongho, there are a couple of problems with your data structure, to my mind anyway.

First, you open the possibility of having multiple answers labeled as correct. Or no correct answers. A good data structure should try to exclude errors by virtue of the structure itself. So I'd have a Question be:
class Question {
vector<Answer> answers
size_t correctAnswer; // index of correct answer.
};

If you know Generic programming, this class will be a template so that Type could be any type
That would requires the vector of Answers to be a vector of pointers to a base class since you can't have a vector of templates with varying instantiations.
@dhayden,
About the design, if u bothered to click on
http://www.cplusplus.com/forum/beginner/246426/#msg1089020
you will notice that i changed my design considerations. I changed my Answer class and in Question, i have a private method to get the correct answer(Maybe that too was supposed to be a std::vector<string>)

It is not a flaw for a Question to have more than one correct Answer. Practically, that happens so that design took consideration of "real life"

My current Question class violates the Single Responsibility Principle by including the mark() and run() methods but it was just for illustration.
Last edited on
@all

I have returned from the depths of my research and I have created the bones to this wonderful code. Be aware that for now I'm just trying to make it work and I am on the verge of success.

I have to give credit to the following:
-Blongho
-http://www.cplusplus.com/forum/beginner/30993/

They each tackled the question in their way and I wanted to do without looking at their code so that I could construct it for myself. Then as I came up with a solution I realized that: files would be best for this project and storing them in an array would be the next best step.

Blongho's suggesting about storing them into an array and generating a random number is brilliant! Mainly because I thought of it too but I wasn't too confident in my skills. This means I'm slowly going in the right direction!

Below is the code:

*Adding notes for those who are learning C++


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <fstream>// Header used to open files.
#include <sstream> //  Still figuring this one out since this was supposed to be used to store info from file to a variable.
#include <string> // Header used to use strings.
#include <cctype> // Used to transform upper/lower case letters to upper/lower case letters.
#include <ctime> // To access time for the srand function.
#include "Windows.h" // Apparently needed because I was getting an error with the srand function since each windows OS is different. 

int main()
{

	std::cout << "This is a chemistry test/quiz?\n";
	std::cout << "Are you ready? Press 'ENTER' to begin." << std::endl;
	std::cin.get();

	//srand((unsigned int)time(NULL)); //used to generate random number but muted out for testing purposes

	int question;
	std::string answer; 
	std::string Mquestion;
	//bool stop = false;// Will be used to see if tester wants to continue with quiz or quit.
	
	//while (stop = false)
	//{
		//question = rand() % 3; //Limits the number being generated from 0-3. Will be used later.
		

		question = 1; // I "generated" a 1 and then converted into a string in the next line.
		std::string s = std::to_string(question);
		Mquestion += "Text" + s + ".txt"; // This should now read "Text1.txt"

		std::ifstream file; // getting ready to open file "ifstream" for Output only.
		file.open(Mquestion, std::ios::out); 

		std::string Squestion;
		std::string Sanswer;
	
		getline(file, Squestion); // A bit stuck here, the file reads the first line and stores it into question. I would like it to read the first line and then skip a line, then read the next line. There's a way to do it but I need to dig deeper. 
		getline(file, Sanswer); //Also the question will be sent to an array as per blongho's suggestion because that will a lot easier.
		std::cout << Squestion << std::endl;
		//std::cout << Sanswer << std::endl; // Used to see if it was doing what I wanted it to do.

		std::string myans; // user's answer

		getline(std::cin, myans);

		if (myans == Sanswer) // the evaluation part.
		{
			std::cout << "correct!" << std::endl;
			std::cin.get();
		}
		else
		{
			exit(1);
		}
	return 0;
}


Text1.txt
How many elements in Helium?
2

_________________________________________________________

Upcoming changes:

-The text file will change to only storing element information and another file will be used only for question.
-Questions will be sent to an array.
-Answer will be sent to a dynamic array.
-Classes will be created to clean up code.

Again I want to thank everyone for providing their input, it has helped me so much on this journey!

Stay tuned for the next draft and the final edition!

Topic archived. No new replies allowed.