6
\$\begingroup\$

I spent a long time searching for ways to create a quiz app and to create a way to sort through non-random questions.

The only way I was able to create was to use a series of 3 dictionaries that are key:value pairs. With 1 being the questions, 1 answers and 1 the explanations for the answers.

The app works by a user choosing true or false and the correct answer being shown then it automatically moves onto the next question. Once all questions are complete the quiz moves onto a screen that displays the summary. To do this I have created empty arrays that get appended to and then transferred into the other view controllers.

I realise my code is awful, but this has been my first major project and the code works but I want to improve my abilities and code properly.

I have attached the critical parts of the program that I believe will help justify my explanation.

// Program Variables

var questionStorage =

[
    "1" : "Red is a four letter word. True or False?" ,
    "2" : "Cat is a three letter word. True or False?",
    "3" : "Dog is a five letter word. True or False",
    "4" : "Animal is a three letter word. True or False",
    "5" : "This is a test. True or False"

]

// True = 1 & False = 0

var questionAnswers =

[

    "1" : "1",
    "2" : "1",
    "3" : "1",
    "4" : "1",
    "5" : "1"


]


var answerExplanations =

[
    "1" : "Red is not a four letter word. Please try again",
    "2" : "This is not true",
    "3" : "Dog is not a four letter word. Please try again",
    "4" : "Test Explanation",
    "5" : "Test Explanation"


    ]

// Game Logic Variables

var incorrectQuestions: [String] = []
var answerExplanation: [String] = []
var correctQuestions: [String] = []
var incorrectQuestionCount = 0
var correctQuestionCount = 0
var currentAnswerExplanation = 1
var questionCount = 1
var currentQuestion = 1
var currentAnswer = 1
var answerPressed = false
var answerSubmitted = false
var progressView: Float = 0.00
var progressIncrease: Float = 0.1

// Program Functions

// Question Generation Function

func Questions() {


    var currentQuestionString = String(currentQuestion)
    var currentAnswerString = String(currentAnswer)
    var answerExplanationString = String(currentAnswerExplanation)


    // Question Selection Variables

    var question = questionStorage[currentQuestionString]
    var answer = questionAnswers[currentAnswerString]
    var explanation = answerExplanations[answerExplanationString]

    // Question Counter Variables


    //countLabel.text = currentQuestionString

    // Question Generation Code

    questionLabel.text = question
    countLabel.text = answer
    answerLabel.hidden = true
    explanationLabel.text = explanation

    progressBar.progress = progressView




}

// Check for quiz completion

func checkFinish() {
    if questionCount == 5 {
        questionLabel.text = "Test Finished"
        answerSummary.hidden = false

    }
}


override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view, typically from a nib.
    // Begin Program

    Questions()
    answerLabel.hidden = true
    answerSummary.hidden = true

    // Timer Begin

    let aSelector : Selector = "updateTime"
    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: aSelector, userInfo: nil, repeats: true)
    startTime = NSDate.timeIntervalSinceReferenceDate()



}

// True & False Button Actions

@IBAction func button1Press(sender: AnyObject) {

    if countLabel.text == "1" && self.answerSubmitted == false { // correct

    //    self.questionLabel.text = "correct"
        self.answerSubmitted = true
        ++self.currentQuestion
        ++self.currentAnswer
        ++self.questionCount
        ++self.currentAnswerExplanation
        ++self.correctQuestionCount
        progressView += 0.02;
        self.correctQuestions.append(self.questionLabel.text!)

        delay(2) {
            self.Questions()
            self.checkFinish()
            self.answerPressed = false
            self.questionNumberLabel.text = "Question \(self.questionCount) / 50"
            self.answerSubmitted = false
        }
    }

    else if countLabel.text == "0" && answerSubmitted == false  { // incorrect

      //  self.questionLabel.text = "correct"
        self.answerSubmitted = true
        ++self.currentQuestion
        ++self.currentAnswer
        ++self.questionCount
        ++self.currentAnswerExplanation
        self.incorrectQuestions.append(self.questionLabel.text!)
        self.answerExplanation.append(self.explanationLabel.text!)
        progressView += 0.02;

        delay(2) {
            self.Questions()
            self.checkFinish()
            self.answerPressed = false
            self.questionNumberLabel.text = "Question \(self.questionCount) / 50"
            self.answerSubmitted = false

            ++self.incorrectQuestionCount

        }

    }
}

@IBAction func button2Press(sender: AnyObject) {

    if countLabel.text == "0" &&  answerSubmitted == false { // correct

     //   self.questionLabel.text = "correct"
        self.answerSubmitted = true
        ++self.currentQuestion
        ++self.currentAnswer
        ++self.questionCount
        ++self.currentAnswerExplanation
        ++self.correctQuestionCount
        self.correctQuestions.append(self.questionLabel.text!)
        progressView += 0.02;

        delay(2) {
            self.Questions()
            self.checkFinish()
            self.answerPressed = false
            self.questionNumberLabel.text = "Question \(self.questionCount) / 50"
            self.answerSubmitted = false
        }

    }

    else if countLabel.text == "1" && answerSubmitted == false { // incorrect

  //      self.questionLabel.text = "correct"
        self.answerSubmitted = true
        ++self.currentQuestion
        ++self.currentAnswer
        ++self.questionCount
        ++self.currentAnswerExplanation
        self.incorrectQuestions.append(self.questionLabel.text!)
        self.answerExplanation.append(self.explanationLabel.text!)
        progressView += 0.02;

        delay(2) {
            self.Questions()
            self.checkFinish()
            self.answerPressed = false
            self.questionNumberLabel.text = "Question \(self.questionCount) / 50"
            self.answerSubmitted = false

            ++self.incorrectQuestionCount
        }
    }
}
\$\endgroup\$
7
\$\begingroup\$

I'm going to post an answer which purely address your set of arrays. You've got three arrays which unnecessarily complicates your logic later on (I haven't even read that far, but I know it to be true).

Consider this... your current setup demands that these three arrays be carefully and perfectly synced at all times.

What would be better is if we had a single array that held all of the information, yes?

There are several approaches we can take. We can use an array of dictionaries:

let kKeyQuestion = "question"
let kKeyAnswer = "answer"
let kKeyExplanation = "explanation"

let questions = [
    [
        kKeyQuestion:"Red is a four letter word. True or false?",
        kKeyAnswer: false,
        kKeyExplanation: "Red is not a four letter word."
    ],
    [
        kKeyQuestion:"Cat is a three letter word. True or False?",
        kKeyAnswer: true,
        kKeyExplanation: "This is true."
    ]
    // etc
]

We could quite similarly do an array of tuples. But it might make most sense to just go ahead and make a QuizQuestion struct.

struct QuizQuestion {
    let question: String
    let answer: Bool
    let explanation: String
}

And create an array full of instances of this struct.

Beyond this, I skimmed your code and it looks like you have a lot of code duplication.

This whole block is duplicated several times throughout your code:

self.answerSubmitted = true
++self.currentQuestion
++self.currentAnswer
++self.questionCount
++self.currentAnswerExplanation
self.incorrectQuestions.append(self.questionLabel.text!)
self.answerExplanation.append(self.explanationLabel.text!)
progressView += 0.02;

delay(2) {
    self.Questions()
    self.checkFinish()
    self.answerPressed = false
    self.questionNumberLabel.text = "Question \(self.questionCount) / 50"
    self.answerSubmitted = false

    ++self.incorrectQuestionCount
}

Let's refactor this out into a separate method, and call that instead of copy & pasting it over and over. Copy and paste is not a design pattern.

\$\endgroup\$
  • \$\begingroup\$ Hey there, Thank you very much for your quick and helpful response! I have spent the better part of 3 hours trying to implement your suggestions and have gone with the route of creating a struct and initialising an array of structs. Though I seem to be stuck and cannot find a solution that I understand. I have made a thread about my problem including the code n stackexchange. The link is here: stackoverflow.com/questions/30666021/… Thank you again for your help! It is greatly appreciated. \$\endgroup\$ – simlimsd3 Jun 5 '15 at 12:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.