Skip to content

Commit

Permalink
Merge pull request #30 from uclaacm/evan-buzzfeed-quiz-edits
Browse files Browse the repository at this point in the history
Evan buzzfeed quiz edits
  • Loading branch information
chasekap authored Dec 10, 2020
2 parents cbc93ec + 9876bb3 commit 1581ca4
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 69 deletions.
87 changes: 87 additions & 0 deletions buzzfeed-style-quiz/src/README.md
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},
...
}
```
7 changes: 3 additions & 4 deletions buzzfeed-style-quiz/src/index.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@


<div class="quiz">

<h2 class="quiz-question">Q1</h2>
<ul data-quiz-question="1">
<li class="quiz-answer" data-quiz-answer="a">a.</li>
<li class="quiz-answer" data-quiz-answer="b">b.</li>
<li class="quiz-answer" data-quiz-answer="c">c. </li>
<li class="quiz-answer" data-quiz-answer="c">c.</li>
<li class="quiz-answer" data-quiz-answer="d">d.</li>
</ul>

Expand Down Expand Up @@ -53,4 +51,5 @@ <h2 class="quiz-question">Q6:</h2>

<div class="quiz-result"></div>


<!-- Magic things that make the quiz work behind the scenes! -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
150 changes: 87 additions & 63 deletions buzzfeed-style-quiz/src/script.js
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();
4 changes: 2 additions & 2 deletions buzzfeed-style-quiz/src/style.less
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ body {
margin-right:10px;
}

&.active {
&.chosen {
&:before {
background-color:#333;
border-color:#333;
Expand All @@ -59,7 +59,7 @@ body {
border-color:red;
}
}
&.active.correct {
&.chosen.correct {
&:before {
outline: 2px solid green;
outline-offset: 2px;
Expand Down

0 comments on commit 1581ca4

Please sign in to comment.