I'm trying to do a simple quiz where it should sum the correct answers and incorrect answers. The thing is although I put two out of three correct answers, I keep getting the same result for the correct and incorrect array: 0. So there must be something wrong at the end, in the evaluate function. Thanks in advance
var responsesArray= [];
var correct=[];
var incorrect= [];
function question2() {
var firstQuestion = prompt('Does null === 0 ? (Yes or No)')
// why do you need to convert the answer to lowercase?
if (firstQuestion.toLowerCase() === 'yes') {
firstQuestion = true
} else if (firstQuestion.toLowerCase() === 'no') {
firstQuestion = false
} else {
// what if the user writes something other than yes or no?
// they will have to answer the question again
alert("Please answer either Yes or No");
return question2();
}
responsesArray.push(firstQuestion); // add the true or false value to the responses array
}
question2();
function question3() {
var js = prompt('What was the original name for JavaScript: Java, LiveScript, JavaLive, or ScriptyScript?');
js = js.toLowerCase();
switch (js) {
// your own answers
case "livescript":
console.log("Correct!");
break;
case "Java":
console.log("wrong");
break;
case "JavaLive":
console.log("wrong");
break;
case "ScriptyScript":
console.log("wrong");
break;
default:
console.log("Sorry the answer is LiveScript");
}
responsesArray.push(js);
var mine = prompt('What coding language is exclusively related to the back-end: Ruby, JavaScript, HTML?');
mine= mine.toLowerCase();
switch (mine) {
// your own answers
case "ruby":
console.log("Yeah!");
break;
case "html":
console.log("ouuu I'm sorry for you");
break;
case "javascript":
console.log("Yeah but so so");
break;
}
responsesArray.push(mine);
}
question3();
function evaluate(responsesArray)
{
for (var i = 0; i < responsesArray.length; i++)
{
if (responsesArray[i] === true|| "livescript" || "ruby")
{
correct++;
} else{
if (responsesArray[i] !== true|| "livescript" || "ruby") {
incorrect++;
}
}
}
Define an array to store the correct answer and then compare correct and user response and easily can identify whether it is correct or not.
Please check below snippet.
var responsesArray= [];
var correct=0;
var incorrect= 0;
//Correct answer key initialize
var index = 0;
//Initialize array to store correct answer.
var correctAnswers = [];
function question2() {
//Save correct answer.
correctAnswers[index++] = "yes";
var firstQuestion = prompt('Does null === 0 ? (Yes or No)')
// why do you need to convert the answer to lowercase?
if (firstQuestion.toLowerCase() === 'yes') {
console.log("correct");
firstQuestion = 'yes'
} else if (firstQuestion.toLowerCase() === 'no') {
console.log("in-correct");
firstQuestion = 'no'
} else {
// what if the user writes something other than yes or no?
// they will have to answer the question again
alert("Please answer either Yes or No");
return question2();
}
responsesArray.push(firstQuestion); // add the true or false value to the responses array
}
question2();
function question3() {
//Save correct answer.
correctAnswers[index++] = "livescript";
var js = prompt('What was the original name for JavaScript: Java, LiveScript, JavaLive, or ScriptyScript?');
js = js.toLowerCase();
switch (js) {
// your own answers
case "livescript":
console.log("Correct!");
break;
case "Java":
console.log("wrong");
break;
case "JavaLive":
console.log("wrong");
break;
case "ScriptyScript":
console.log("wrong");
break;
default:
console.log("Sorry the answer is LiveScript");
}
responsesArray.push(js);
//Save correct answer.
correctAnswers[index++] = "ruby";
var mine = prompt('What coding language is exclusively related to the back-end: Ruby, JavaScript, HTML?');
mine= mine.toLowerCase();
switch (mine) {
// your own answers
case "ruby":
console.log("Yeah!");
break;
case "html":
console.log("ouuu I'm sorry for you");
break;
case "javascript":
console.log("Yeah but so so");
break;
}
responsesArray.push(mine);
//Call function to evaluate correct or incorrect answer
evaluate(responsesArray,correctAnswers)
}
question3();
function evaluate(responsesArray,correctAnswers)
{
for (var i = 0; i < responsesArray.length; i++)
{
//Match response with correct answer.
if (responsesArray[i] === correctAnswers[i])
{
correct++;
} else{
if (responsesArray[i] !== correctAnswers[i]) {
incorrect++;
}
}
}
alert("Correct : "+correct+" and Incorrect : "+incorrect);
}
The way you test for correct answers is wrong. Instead define an array with the correct answers and verify them as follows:
var correct = incorrect = 0; // better initialise your variables
function evaluate(responsesArray) {
var correctAnswers = [true,"livescript","ruby"];
for (var i = 0; i < responsesArray.length; i++) {
if (responsesArray[i] === correctAnswers[i]) {
correct++;
} else {
incorrect++;
}
}
}
What you had was:
if (responsesArray[i] === true|| "livescript" || "ruby"){
But this means:
if the answer was true, or .... "livescript" is true, or ... "ruby" is true, then
As JavaScript considers strings to be truthy, the if condition would always be true.
Note also that there is no need to do a second if, since the else part is only executed if the first if condition was false, which means you already have filtered for the cases where the answer was wrong.
Finally, your counter variables should be defined before you start incrementing them. It works without this definition, but if one of the two variables is not incremented, it will still be undefined after your call to evaluate. Better always define your variables.
Related
Thank you for answering my original question, and the reason i am simply editing this post for my second question about this code is because the site wont let me make very many questions. my question is why isnt makesjump1 randomly true or false? it always seems to come out true. please help #Yhlas and #codeConcussion
var isjumping1 = true;
while(isjumping1) {
var makesjump1 = Math.random()
if(makesjump1 => .51) {
makesjump1 = true }
else if(makesjump1 <= .50) {
makesjump1 = false }
var jump1 = prompt("Do you choose to JUMP, or let the fairies help you FLY").toUpperCase()
switch(jump1) {
case 'JUMP':
if(makesjump1 = true) {
console.log("You made the jump on your own, so the fairies reward you with a steel sword(9 DMG)")
damage = 9;
weapon = 'steel sword(9 DMG)'; }
else if(makesjump1 = false) {
console.log("You attempt the jump but miss it, and are hanging on by a thread")
console.log("The fairies rescue you, but you got scratched up, doing 3 damge to you.")
health = health - 3; }
isjumping1 = false;
break;
case 'FLY':
console.log("The fairies help you over the pit")
isjumping1 = false;
break;
default:
alert("That was not a choice!")
break; }
}
You're assigning it to true with every loop. Use == instead or just...
while(isjumping1)
while(isjumping1==1) - comparison
while(isjumping1=1) - assignment(always returns true)
The way that you're assigning the random value to makesjump1 is incorrect. It would fail if Math.random() returned a value in the range (0.50,0.51). Instead, try this:
var makesjump1 = Math.random()<0.5;
after days of hard thinking i choose to ask that question. I have if statement with multiple conditions:
//var current is array of arrays of integers
if((current[rot][0] + x)<blocks.length
&& (current[rot][1] + x)<blocks.length
&& (current[rot][2] + x)<blocks.length
&& (current[rot][3] + x)<blocks.length
&& !$(blocks[current[rot][0]+x]).hasClass("blockLand")
&& !$(blocks[current[rot][1]+x]).hasClass("blockLand")
&& !$(blocks[current[rot][2]+x]).hasClass("blockLand")
&& !$(blocks[current[rot][3]+x]).hasClass("blockLand"))
{
//something to happen here ONCE!
}
Because i want something inside to happen just once i think i cant use for loop.
So my question is: is there a possible way to reduce the conditions number? and how?
P.S.: Yes i figured out that i can use flag (true/false) inside and do my stuff outside this if, in another if - but i think that not always gonna work, because for every loop the flag will be different.
var b = true;
for (var i = 0; i <= 3; i++) {
// In two lines for being clear, but it's possible just in one
b = b && (current[rot][i] + x)<blocks.length
b = b && !$(blocks[current[rot][i]+x]).hasClass("blockLand");
// You could speed it up this way.
if(!b) break;
}
if (b) {
//something to happen here ONCE!
}
I think I understand what you are asking but let me know if there is anything else I can do.
JavaScript has a ternary (conditional operator) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
This operator allows you to assign true/false values based on an internal if/else condition.
Here is some code for you to explain this...
window.onload = function() {
var one = 1;
var two = 2;
console.log(one > two ? "greater" : "not greater");
};
You can also use a Switch statement which you can read about here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch.
Here is an example of a switch statement.
window.onload = function() {
var string = "testing this out";
switch (string) {
case "testing this out":
console.log('testing this out found in condition one');
break;
case "testing":
console.log('found testing');
break;
default:
console.log('not found');
break;
}
};
Let me know if I can improve this.
I am trying to create a JavaScript Quiz.
The function will check the user's input value.
If it is correct; it will change the question.
Exact Code See JSFiddle
There are probably many more efficient and conventional ways to achieve what I am trying to do. Current issue is the function runs from the top every time it runs(obviously)
function checkAnswer() {
var question = document.getElementById("ques").innerHTML;
var userAnswer = document.getElementById("answer").value;
if (userAnswer === "New York City") {
alert("correct!");
question = "What is the best college football team?";
if (userAnswer === "Alabama") {
alert("Correct!");
question = "Next question will go here and so on..."
}
}
}
In no way would I suggest doing things this way, but here's how to get your jsfiddle to work:
function check() {
var question = document.getElementById('question').innerHTML
var userAnswer = document.getElementById("answer").value;
//Makes answer lowercase
userAnswer = userAnswer.toLowerCase();
//question one
if (question === "Write One, Two, Three..") {
if (userAnswer === "one two three") {
alert('correct');
}
else {
alert('Sorry Wrong!');
}
//question two
document.getElementById('question').innerHTML = "Write 4, 5, 6";
}
else {
if (userAnswer === "4 5 6") {
alert("correct!");
}
else {
alert('Sorry Wrong!');
}
}
}
One simple way to do what you want is to put your questions in an array:
var QandA = [
["question1...", "answer1...."],
["question2...", "answer2...."],
["question3...", "answer3...."],
["question4...", "answer4...."]
];
function check()
{
// No more questions?
if (0 === QandA.length) return;
// Check answer
var userAnswer = document.getElementById("answer").value.toLowerCase();
if (userAnswer === QandA[0][1]) {
alert("Correct");
}
else {
alert("Incorrect");
}
// Delete that question
QandA.shift();
// And move to next
if (0 != QandA.length) {
document.getElementById('question').innerHTML = QandA[0][0];
}
}
If you have a number of questions that you need validating I would take the following approach. It allows you as many questions as you like without repeating code.
First, store your questions in an array:
var arr = ["one two three", "4 5 6"];
Set a counter to zero, and a total (to measure the user performance):
var count = 0;
var total = 0;
Cache the elements:
var questionEl = document.getElementById('question');
var userAnswerEl = document.getElementById("answer");
Separate out the code that writes the question into a new function. It writes the question based on the counter:
function writeQuestion() {
if (count < arr.length) {
questionEl.innerHTML = "Write " + arr[count];
} else {
alert('No more questions. You have scored ' + total);
}
}
function check() {
userAnswer = userAnswerEl.value.toLowerCase();
if (userAnswer === arr[count]) {
alert('correct');
count++;
total++;
writeQuestion();
} else {
alert('Sorry Wrong!');
count++;
writeQuestion();
}
}
DEMO
if (userAnswer === "New York City") {
alert("correct!");
question = "What is the best college football team?";
if (userAnswer === "Alabama") {
alert("Correct!");
question = "Next question will go here and so on..."
}
}
This block only runs if userAnswer is "New York City", but inside it, you test whether userAnswer is "Alabama" - that will never be true. You probably want to move the second if outside of the first if block.
You seem to be assigning to question but not using the value. If you think you are updating the question text by assigning a value to question that isn't going to work. I think you are trying to do this:
question = document.getElementById("ques");
// later on...
question.innerHTML = "this is another question";
// even later...
question.innerHTML = "and here is a new question";
That would update the page for you because question would point to a DOM node and you can set .innerHTML on that, but the way you wrote it, you're setting question to a string value initially, and then other string values later, but not using any of them in anyway.
i'd like to use the return value of a specific function as the condition of an if statement. Is that possible ?
I'm basically building a string inside a function that takes an array (the conditionArray) and concatenates it to a statement.
Then it returns this condition as a string.
After that, i wanted to use this string as the condition of my if-statement.
My current problem looks something like that.
var answer = prompt("Tell me the name of a typical domestic animal");
var conditionArray = new Array("Dog", "Turtle", "Cat", "Mouse")
function getCondition(conditionArray) {
for (i = 0; i < conditionArray.length; i++) {
if (i != conditionArray.length) {
condition += 'answer === ' + conditionArray[i] + ' || ';
} else {
condition += 'answer === ' + conditionArray[i];
}
return condition;
}
}
if (getCondition(conditionArray)) {
alert("That is correct !");
} else {
alert("That is not a domestic animal !");
}
For this type of test use Array.prototype.indexOf, x = arr.indexOf(item)
x === -1 means item is not in arr
Otherwise x is the index of arr that the first occurrence of item is located
var options = ["Dog", "Turtle", "Cat", "Mouse"],
answer = prompt("Tell me the name of a typical domestic animal");
// some transformation of `answer` here, i.e. casing etc
if (options.indexOf(answer) !== -1) {
alert("That is correct !");
} else {
alert("That is not a domestic animal !");
}
The best way to do this kind of test is to use Array.prototype.indexOf. See Paul's answer for more details on how to use it.
--
If you really really want to return a condition, you can use eval() to evaluate the condition string. Keep in mind that eval() is dangerous though. It's usage isn't recommended. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Don%27t_use_eval_needlessly!
if (eval(getCondition(conditionArray))) {
alert("That is correct !");
} else {
alert("That is not a domestic animal !");
}
I got a script using TONS of if statement to do a task... But....
Most of them repeated like:
if (parent.getObject()=='apple') {
if (datatype('fruit')){
//do a
parent.setObjectType('fruit');
}
else if (datatype('beverage')){
//do a
parent.setObjectType('beverage');
}
}
else if (parent.getObject()=='banana') {
if (datatype('fruit')){
//do a
parent.setObjectType('fruit');
}
else if (datatype('beverage')){
//do a
parent.setObjectType('beverage');
}
}
else if (parent.getObject()=='coconut') {
if (datatype('fruit')){
//do a
parent.setObjectType('fruit');
}
else if (datatype('beverage')){
//do a
parent.setObjectType('beverage');
}
}
else if (parent.getObject()=='Dewberry') {
if (datatype('fruit')){
//do a
parent.setObjectType('fruit');
}
else if (datatype('beverage')){
//do a
parent.setObjectType('beverage');
}
}
Is it possible for me to minimize the use of those repeated codes?
I don't want to use up all the spaces only with lines of if else statement...
I'm not sure whether your actual code is a bit more diverse, but what you have posted can exactly be replicated by
if (['apple', 'banana', 'coconut', 'Dewberry'].some(function(fruit) {
return parent.getObject()==fruit;
}) {
var type = ['fruit', 'beverage'].find(datatype);
if (type) {
//do a
parent.setObjectType(type);
}
}
(where the find function is something like the following
Array.prototype.find = function(predicate, context) {
for (var i=0; i<this.length; i++)
if (predicate.call(context, this[i], i))
return this[i];
return null;
};
Without seeing more code maybe you could use something like this:
function doTask(a, b) {
var as_string = a + ";" + b;
switch (as_string) {
case "1;1":
//code when a=1 and b=1
break;
case "1;2":
//code when a=1 and b=2
break;
}
}
var a = 1;
var b = 1;
doTask(a, b);
You may or may not be able to reduce if statements depending on your code.
For example if you're adding odd numbers from 0 to n, you an either loop from 0 to n and use if statements to check if the number is odd. However if you happen to know Gauss's rule 1/2*n*(n+1), you can compute this value in one line without any looping or conditional statements (by removing the k(k+1); k even numbers).
You can simply use The switch Statement, it's more efficient in the case you have many possible values:
switch (parent.getObject()) {
case "apple":
switch (datatype) {
case "fruit":
//Task //do task a
//do task b with value 1
break;
case "beverage":
//do task a
//do task b with value 2
break;
}
break;
case "banana":
// Task a with ...
break;
// And put all your possible values
}
You have just to manage the possible vlaues of parent.getObject() and datatype.