-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #30 from uclaacm/evan-buzzfeed-quiz-edits
Evan buzzfeed quiz edits
- Loading branch information
Showing
4 changed files
with
179 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# Buzzfeed style quiz (make your own!) | ||
|
||
## A brief refresher on dictionaries | ||
By this point we have already covered variables and introduced the Array data structure. | ||
|
||
A dictionary is simply another data structure that is at our disposal. Let's see what makes it so special and powerful. | ||
|
||
Think about what you would find in a normal English dictionary. For example, if you wanted to know the definition of the word "Brownie" you'd just look it up in a dictionary and get the following description: | ||
|
||
``` | ||
Brownie: a baked rectangle of rich chocolate cake without the addition of blueberries | ||
``` | ||
|
||
We might logically call the above a **dictionary entry** with the word `Brownie` and the description `a baked rectangle of rich chocolate cake without the addition of blueberries`. | ||
|
||
In JavaScript, we use slightly different terminology when referencing dictionaries. The word `Brownie` is called a **key** and the description `a baked rectangle of rich chocolate cake without the addition of blueberries` is called a **value**. | ||
|
||
To declare a dictionary variable, simply use curly braces `{}` and a colon `:` to separate your **key** from your **value**. Note that we can use commas `,` to separate dictionary entries. | ||
```js | ||
let my_recipe_dictionary = { | ||
"Brownie": "a baked rectangle of rich chocolate cake without the addition of blueberries", | ||
"Cake": "not a lie", | ||
} | ||
``` | ||
But what if we wanted to get values out of the dictionary? What good is a recipe dictionary if you can't access any recipes? To do this we use the same square bracket notation `[]` as Arrays | ||
```js | ||
let brownie_description = my_recipe_dictionary["Brownie"] | ||
``` | ||
Note that in the above examples the **values** are strings. but they can also be Numbers, or any type of JavaScript variable type. | ||
```js | ||
let my_multi_value_dictionary = { | ||
"my first entry": 1, //A Number value is okay | ||
"another entry": false, //A Boolean value is also okay | ||
"last entry": [], //Even an Array value is okay! | ||
} | ||
``` | ||
Lastly, a bit more terminology. You might frequently hear the term **map** or **mapping** used when describing dictionaries. This simply means that a certain **key** leads to a certain **value**. For example, in the above `my_multi_value_dictionary` we might say that `"my first entry"` **maps** to `1`. | ||
|
||
This is what makes dictionaries so powerful: the ability to model mappings or associations. After all, our code is meant to model the real world. Think of the many things you encounter in your everday life that you could store in a dictionary. The power of dictionaries might not be readily apparent right now, so let's jump into the project | ||
|
||
## Getting started | ||
One of the most important skills you can have as a software developer is being able to read code that other people have written and understanding what it's trying to do. (Think translating JavaScript back to English). | ||
|
||
Let's walk through the code in `script.js` together. | ||
|
||
See if you can find the `questions` dictionary at the top of `script.js` | ||
```js | ||
let questions = { | ||
//This should be changed! | ||
'Q1': {'a':1,'b':2,'c':3,'d':4}, | ||
'Q2': {'a':2,'b':3,'c':4,'d':1}, | ||
'Q3': {'a':2,'b':4,'c':1,'d':3}, | ||
'Q4': {'a':3,'b':1,'c':2,'d':4}, | ||
'Q5': {'a':1,'b':2,'c':3,'d':4}, | ||
'Q6': {'a':1,'b':2,'c':3,'d':4} | ||
} | ||
``` | ||
Each entry in the 'questions' dictionary represents a specific question, for example the first entry is for Question 1. | ||
|
||
Here's the kicker though: the values field for each entry is ANOTHER dictionary. (Remember how values in a dictionary can be any JavaScript variable type?) | ||
|
||
Can you guess what the inner dictionary represents? Each entry in the inner dictionary contains a mapping from answer choice to what category that answer choice represents. | ||
|
||
In our quiz each answer to each question represents a category | ||
For example in the following question: | ||
``` | ||
What trait best describes you: | ||
a: bravery | ||
b: loyalty | ||
c: knowledge | ||
d: ambition | ||
``` | ||
``` | ||
Answer choice a represents Gryfindor | ||
Answer choice c represents Hufflepuff | ||
Answer choice b represents Ravenclaw | ||
Answer choice d represents Slytherin | ||
``` | ||
All we have to do now is decide how we want to represent our different categories: `Gryfindor`, `Hufflepuff`, `Ravenclaw`, and `Slytherin`. For example, we could use `1` to represent Gryfindor, `2` to represent Hufflepuff, and so on. | ||
|
||
So with all that in mind, can you see how the the first dictionary entry perfectly models our example Hogwarts House question? | ||
```js | ||
{ | ||
'Q1': {'a':1,'b':2,'c':3,'d':4}, | ||
... | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,102 +1,126 @@ | ||
//Big thanks to tgallimore for graciously providing the | ||
//groundwork for this code skeleton! | ||
let questions = { //This should be changed! | ||
1 : {'a':1,'b':2,'c':3,'d':4}, | ||
2: {'a':2,'b':3,'c':4,'d':1}, | ||
3: {'a':2,'b':4,'c':1,'d':3}, | ||
4: {'a':3,'b':1,'c':2,'d':4}, | ||
5: {'a':1,'b':2,'c':3,'d':4}, | ||
6: {'a':1,'b':2,'c':3,'d':4} | ||
let questions = { | ||
//This should be changed! | ||
'Q1': {'a':1,'b':2,'c':3,'d':4}, | ||
'Q2': {'a':2,'b':3,'c':4,'d':1}, | ||
'Q3': {'a':2,'b':4,'c':1,'d':3}, | ||
'Q4': {'a':3,'b':1,'c':2,'d':4}, | ||
'Q5': {'a':1,'b':2,'c':3,'d':4}, | ||
'Q6': {'a':1,'b':2,'c':3,'d':4} | ||
} | ||
|
||
function calculateAnswer(results){ | ||
let oneScore = results[1] | ||
let twoScore = results[2] | ||
let threeScore = results[3] | ||
let fourScore = results[4] | ||
let result = "hello" //this shoud be changed! | ||
let result = "hello" //this shoud be changed! | ||
|
||
//Start with some if statments! | ||
return "hello" | ||
|
||
|
||
} | ||
|
||
|
||
let Quiz = function(){ | ||
let self = this; | ||
let myQuiz = this; | ||
this.init = function(){ | ||
self._bindEvents(); | ||
} | ||
this.questionNumber = 1 | ||
this.counts = {1: 0, 2:0, 3:0, 4:0} | ||
|
||
// TODO | ||
//TODO | ||
this._pickAnswer = function($answer, $answers){ | ||
$answers.find('.quiz-answer').removeClass('active'); | ||
$answer.addClass('active'); | ||
} | ||
$('.quiz-answer').on('click', function(){ | ||
let selectedAnswer = $(this); | ||
pickAnswer(selectedAnswer); | ||
|
||
this._calcResult = function(){ | ||
let test = [] | ||
$('ul[data-quiz-question]').each(function(i){ | ||
var $this = $(this), | ||
chosenAnswer = $this.find('.quiz-answer.active').data('quiz-answer'), | ||
correctAnswer; | ||
test.push(chosenAnswer) | ||
}); | ||
console.log(test) | ||
for(let i =0; i< test.length;i++){ | ||
let answer = test[i] | ||
let cata = questions[i+1][answer] | ||
this.counts[cata] += 1 | ||
if ( myQuiz._isComplete() ) { | ||
scrollToAnswerSection(); | ||
myQuiz._showResult( myQuiz._calcResult() ); | ||
deactivateQuiz(); | ||
} | ||
return calculateAnswer(this.counts) | ||
|
||
}); | ||
} | ||
this.catagoryCounts = {1:0, 2:0, 3:0, 4:0} | ||
|
||
|
||
|
||
this._calcResult = function(){ | ||
let chosenAnswers = getAllChosenAnswers() | ||
console.log(chosenAnswers) | ||
|
||
for(let i = 0; i < chosenAnswers.length; i++){ | ||
let answer = chosenAnswers[i] | ||
let questionNumber = getQuestionNumber(i); | ||
let catagory = questions[questionNumber][answer] | ||
this.catagoryCounts[catagory] += 1 | ||
} | ||
return calculateAnswer(this.catagoryCounts) | ||
} | ||
|
||
this._isComplete = function(){ | ||
var answersComplete = 0; | ||
$('ul[data-quiz-question]').each(function(){ | ||
if ( $(this).find('.quiz-answer.active').length ) { | ||
answersComplete++; | ||
} | ||
}); | ||
let answersComplete = getNumberCompleteAnswers(); | ||
if ( answersComplete >= 6 ) { | ||
return true; | ||
} | ||
else { | ||
return false; | ||
} | ||
} | ||
|
||
this._showResult = function(result){ | ||
$('.quiz-result').addClass('good').html(result); | ||
renderResult(result); | ||
highlightResultGreen(); | ||
} | ||
} | ||
|
||
/* | ||
* More magic that makes things work behind the scenes! | ||
* We've moved most of the complex logic into these | ||
* helper functions so you won't have to worry about | ||
* it (and so the above code reads more like English). | ||
* You don't have to touch any of the code below this | ||
* comment, and messing with it might break your quiz. | ||
* If you're curious, however, feel free to see if you | ||
* can understand what's going on here! | ||
*/ | ||
function getNumberCompleteAnswers() { | ||
let numCompleteAnswers = 0; | ||
$('ul[data-quiz-question]').each(function(){ | ||
if ( $(this).find('.quiz-answer.chosen').length ) { | ||
numCompleteAnswers++; | ||
} | ||
}); | ||
return numCompleteAnswers; | ||
} | ||
|
||
function pickAnswer(selectedAnswer){ | ||
let allPossibleAnswers = selectedAnswer.closest('ul[data-quiz-question]'); | ||
allPossibleAnswers.find('.quiz-answer').removeClass('chosen'); | ||
selectedAnswer.addClass('chosen'); | ||
} | ||
|
||
function scrollToAnswerSection(){ | ||
$('html, body').animate({ | ||
scrollTop: $('.quiz-result').offset().top | ||
}); | ||
} | ||
|
||
this._bindEvents = function(){ | ||
$('.quiz-answer').on('click', function(){ | ||
var $this = $(this), | ||
$answers = $this.closest('ul[data-quiz-question]'); | ||
self._pickAnswer($this, $answers); | ||
if ( self._isComplete() ) { | ||
|
||
// scroll to answer section | ||
$('html, body').animate({ | ||
scrollTop: $('.quiz-result').offset().top | ||
}); | ||
function deactivateQuiz() { | ||
$('.quiz-answer').off('click'); | ||
} | ||
|
||
self._showResult( self._calcResult() ); | ||
$('.quiz-answer').off('click'); | ||
function getAllChosenAnswers() { | ||
let chosenAnswers = []; | ||
$('ul[data-quiz-question]').each(function(questionNumber, question){ | ||
let chosenAnswer = $(question).find('.quiz-answer.chosen').data('quiz-answer') | ||
chosenAnswers.push(chosenAnswer); | ||
}); | ||
return chosenAnswers; | ||
} | ||
|
||
} | ||
}); | ||
} | ||
function renderResult(result) { | ||
$('.quiz-result').html(result); | ||
} | ||
var quiz = new Quiz(); | ||
|
||
highlightResultGreen = () => { $('.quiz-result').addClass('good') } | ||
highlightResultOrange = () => { $('.quiz-result').addClass('mid') } | ||
highlightResultRed = () => { $('.quiz-result').addClass('bad') } | ||
|
||
getQuestionNumber = (i) => {return `Q${i+1}`} | ||
|
||
let quiz = new Quiz(); | ||
quiz.init(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters