WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

Day 35 Challenge

Forums > 100 Days of SwiftUI

I've gotten the challenge (Edutainment app for multiplication tables), but I'm wondeirng what designs others came up with. Anyone have screenshots or clips of how they animated? Didn't find much on the forums re design, mostly code questions.

Thanks

   

I'm working on it now but am struggling with creating a Question struct with a method to build a questions and answers array of all possible questions and answers. Don't know how to create an instance of the Question struct and make the questions and answers array available in the ContentView. There is a post on the forum with the same title as yours to which I posted my issues but haven't gotten any replies so kind of stuck.

I did go ahead and build some logic to create a quiz array from the questions and answers array based on user input for times table to practice and number of desired questions. I build that in a Playground with a manually built questions and answers array and it now appears to work base on user inputs. That code is below. There is without a doubt a more elegant solution to creating the quiz array but without any additional hints I went ahead with my logic. I kind of brute forced the creation of the quiz array but it works. Would be interested in yours and any other more elegant solutions.

If you could provide some insight into building a Question struct that creates a questions and answers array that I can make available in ContentView that would be much appreciated. :-) Here is the Questions struct I build to create a questions and answers array. Just don't know how to make the array available in ContentView.

struct Question {
    var questionsArray = [String]()

    mutating func buildQuestionsArray() {
        for i in 2...12 {
            for j in 1...12 {
                questionsArray.append("What is \(i) x \(j)?")
                questionsArray.append("\(i) x \(j) = \(i * j).")
            }
        }
    }
}

Here is my code to create a quiz array from a questions and answers array. I build it in a Playground so does not include a ContentView.

// Manual creation of a questions and answers array. For testing just used the 2 times and 3 times tables.
var myTimesTable = ["What is 2 x 1?", "2 x 1 = 2", "What is 2 x 2?", "2 x 2 = 4", "What is 2 x 3?", "2 x 3 = 6", "What is 2 x 4?", "2 x 4 = 8","What is 2 x 5?", "2 x 5 = 10","What is 2 x 6?", "2 x 6 = 12","What is 2 x 7?", "2 x 7 = 14", "What is 2 x 8?", "2 x 8 = 16", "What is 2 x 9?", "2 x 9 = 18", "What is 2 x 10?", "2 x 10 = 20","What is 2 x 11?", "2 x 11 = 22", "What is 2 x 12?", "2 x 12 = 24", "What is 3 x 1?", "3 x 1 = 3", "What is 3 x 2?", "3 x 2 = 6", "What is 3 x 3?", "3 x 3 = 9", "What is 3 x 4?", "3 x 4 = 12","What is 3 x 5?", "3 x 5 = 15","What is 3 x 6?", "3 x 6 = 18","What is 3 x 7?", "3 x 7 = 21", "What is 3 x 8?", "3 x 8 = 24", "What is 3 x 9?", "3 x 9 = 27", "What is 3 x 10?", "3 x 10 = 30","What is 3 x 11?", "3 x 11 = 33", "What is 3 x 12?", "3 x 12 = 36"]

//Create a quiz array based on desired times table. Will filter for number of questions later in code
func createQuizArray(timesTable: Int, numberOfQuestions: Int) {
    var quizArray = myTimesTable

    //Create tempArray to facilitate building of quiz array
    var tempArray = [String]()
    var startIndex = Int()

    /*Determine quizArray starting index of selected times table elements. Each times table question and answer block has
     24 elements, e.g., 2 times table would have "What is 2 x 1?" and then "2 x 1 = 2" ...thru "12 x 12 = 144" The block for the 2 times table starts at index 0.*/
    switch timesTable {

    case 2:
        startIndex = 0
    case 3:
        startIndex = 24
    case 4:
        startIndex = 48
    case 5:
        startIndex = 96
    case 6:
        startIndex = 120
    case 7:
        startIndex = 148
    case 8:
        startIndex = 172
    case 9:
        startIndex = 196
    case 10:
        startIndex = 220
    case 11:
        startIndex = 244
    default:
        startIndex = 268
    }

   //Append to tempArray (that starts out empty) the elements of the desired times table question and answer block from the quizArray.
for i in 1...24 {
    tempArray.append(quizArray[startIndex + (i - 1)])
    }
 //Populate quizArray with the block of questions from tempArray
quizArray = tempArray
//Remove all elements from tempArray to start fresh with an empty array
    tempArray.removeAll()

//Populate tempArray with random questions and answers from quizArray based on user input of desired number of questions
    for _ in 1...numberOfQuestions {
    var randomQuestion = Int.random(in: 0...22)
    //The randomQuestion variable will be a pointer to quizArray question elements so have to make sure it points to the correct the correct element. Question elements start at [0] and then every even element and answers start on [1] and then every odd element.
        if randomQuestion != 0 && randomQuestion % 2 != 0 || randomQuestion % 2 == 1 {
        randomQuestion += 1
    }
    tempArray.append(quizArray[randomQuestion])
    tempArray.append(quizArray[randomQuestion + 1])
}
    //Repopulate the quizArray with final questions and answers from tempArray
    quizArray = tempArray
    tempArray.removeAll()
    print(quizArray)
}

createQuizArray(timesTable: 3, numberOfQuestions: 20)

   

check out Sara's

   

Hausmark says:

I'm ... struggling with creating a Question struct with a method to build a questions and answers

Now might be a good time to Step Away From The Code.

Have a converstation with yourself and ask, "Haus? What, exactly, is a question here?"

Your answer above is a struct (named Question) that contains what exactly? It contains an array of String. Be honest! Is an array of String really a maths question?

Parts of a Maths Quiz Question


Now, dig in. Ask yourself what are the parts that make up a maths multiplication quiz question? And once you have the parts, what would you likely do with those parts?

You might noodle through these questions ending with this short list:

  1. First Operand
  2. Second Operand
  3. Proper Answer
  4. String form suitable for display

Using these user requirements, you might then create a simple Problem struct like this:

// Multiplication Problem Struct
// Paste into Playgrounds
struct Problem {
    var operand_1 = 0   // First number in the quiz problem
    var operand_2 = 0   // Second number in the quiz problem

    var answer: Int {  // Calculate the answer.
        operand_1 * operand_2
    }

    var quizLabel: String {  // Calculate the string!
        "\(operand_1) x \(operand_2) = "
    }
}

// Create a maths problem
let p1 = Problem(operand_1: 5, operand_2: 4)
p1.quizLabel  // Ask the object for its quizLabel
p1.answer     // Ask the object for its answer

let p2 = Problem(operand_1: 7, operand_2: 7)
p2.quizLabel
p2.answer

This is a concept known as "Keep It Super Simple", aka the KISS principle. A single problem only knows about its two operands, its answer, and knows how to generate a label. It does nothing else!

Now, when ever you've created a maths problem, you never need to hand craft the label, or calculate the answer. You've encapsulated these responsibilities to the Problem struct. Just ask the struct to give you the answer, or the quizLabel.

Nota bene:
Some define KISS as Keep it Simple, Stupid. And I've seen it as Keep it Stupidly Simple. Pick the definition suitable for your classroom.

   

Now that you've defined a proper maths problem, how can you use this object to create a quiz? Again, step away from the code. WIth paper and pencil, write down a simple quiz, then identify the parts of the quiz. You'll use these parts in your Quiz struct.

Parts of a Quiz Struct


Your notes and requirements may be different. But I came up with these:

  1. Base operand.
  2. Maximum value for second operand.
  3. Array containing all the Problems

So define a Quiz struct and code in these requirements. I hope you are using Playgrounds to quickly test and modify your work?

// Multiplication Quiz Struct
// Paste into Playgrounds
struct Quiz {
    // These are DEFAULT values. Change as necessary
    var baseOperand         = 5  // DEFAULT: Calculate the FIVE times table
    var maxValueForOperand2 = 10 // DEFAULT: 5 x 10 is the highest for this quiz

    // Create one Problem object for each combination
    // quizQuestions is an ARRAY of problem objects
    var quizQuestions: [Problem]  {
        var problems = [Problem]() // empty array
        for operand2 in 1...maxValueForOperand2 {
            // Add the problem to the problems array
            problems.append(Problem(operand_1: baseOperand, operand_2: operand2))
        }
        return problems
    }
}

// Create a NEW quiz. Change the DEFAULT values
let todaysQuiz = Quiz(baseOperand: 2, maxValueForOperand2: 14)
todaysQuiz.quizQuestions              // See all the quiz questions.
todaysQuiz.quizQuestions[4].quizLabel // See quiz question #4
todaysQuiz.quizQuestions[4].answer    // See quiz answer #4

let randomQuizQuestion = todaysQuiz.quizQuestions.randomElement()!  // Pick a RANDOM quiz question
randomQuizQuestion.quizLabel
randomQuizQuestion.answer

// Use the power of arrays to SHUFFLE the quiz questions into a random order
let tomorrowsQuiz = Quiz(baseOperand: 6, maxValueForOperand2: 10)
let popQuiz = tomorrowsQuiz.quizQuestions.shuffled() // Shuffle the order

// Display the popQuiz problems
popQuiz.forEach { problem in
    print(problem.quizLabel)
}

   

Very much appreciated @Obelix. Just what I needed.

   

Save 50% in my Black Friday sale.

SAVE 50% To celebrate WWDC22, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.