sw2020
sw2020

Reputation: 195

Is there a better way to implement?

I am asking the user 10 multiple choice questions once the questions are answered I would like a result to appear based on their answers. I was wondering if there was a better method of figuring out their score then just doing lots of if statements?

Int result = 100;
if (answer1 == 10) {
  result = result +10;

  if (answer2 ==20 ) {
    result = result -5;

    if (answer3 == 50) {
      result = result +20;
    }
    else if (answer3 == 10)

    ...

and it will carry on...

Upvotes: 0

Views: 140

Answers (3)

Aravind Yarram
Aravind Yarram

Reputation: 80166

It is easier to implement if you model it properly. I am not sure about your problem context but making few assumptions here is what I came up with.

Narrative

A Quiz is a set of Question's. Each Question has one or more Answer's, each Answer carrying a certain weight. You prepare the Quiz for a particular scenario (Java, c#) and present to the user one by one. User selects an answer for the presented question and then you display him the currentScore and next question. After all the questions are presented a finalScore is calculated.

Abstractions

  • Quiz (prepare, currentScore(), finalScore())
  • Question (scoreFor)
  • Answer (weightedScore)

Implementation

public class Quiz
{
    List<Question>  questions       = new ArrayList<Question>();
    List<String>    selectedAnswers = new ArrayList<String>();
    private int     currentScore;

    public void prepare()
    {
        questions.add(new Question("What comes after A?", Arrays.asList(new Answer("B", 10), new Answer("Z", 5))));
        questions.add(new Question("What comes after B?", Arrays.asList(new Answer("A", -5), new Answer("C", 10))));
    }

    public int finalScore()
    {
        int result = 0;
        for (int i = 0; i < questions.size(); i++)
        {
            result = result + questions.get(i).scoreFor(selectedAnswers.get(i));
        }
        return result;
    }

    public void setSelectedAnswerFor(int questionIndex, String selectedAnswer)
    {
        assert questionIndex < questions.size();
        selectedAnswers.add(questionIndex, selectedAnswer);
        currentScore = currentScore +    questions.get(questionIndex).scoreFor(selectedAnswer);
    }

    public int currentScore()
    {
        return currentScore;
    }

    public static void main(String args[])
    {
        Quiz quiz = new Quiz();
        quiz.prepare();
        quiz.setSelectedAnswerFor(0, "B");
        System.out.println("Current Score " + quiz.currentScore());
    quiz.setSelectedAnswerFor(1, "A");
    System.out.println("Current Score " + quiz.currentScore());
    System.out.println("Final Score " + quiz.finalScore());
    }
}

public class Question
{
    private final String                text;
    private final Map<String, Integer>  weightedAnswers;

    public Question(String text, List<Answer> possibleAnswers)
    {
        this.text = text;
        this.weightedAnswers = new HashMap<String, Integer>(possibleAnswers.size());
        for (Answer ans : possibleAnswers)
        {
            weightedAnswers.put(ans.text, ans.score);
        }
    }

    public int scoreFor(String selectAnswer)
    {
        return weightedAnswers.get(selectAnswer);
    }

    public String getText()
    {
        return text;
    }
}

public class Answer
{
    final String    text;

    final int       score;

    public Answer(String text, int score)
    {
        this.text = text;
        this.score = score;
    }

}

Output

Current Score 10
Current Score 5
Final Score 5

That solution can be enhanced but the point is to represent the solution in terms of business concepts (ubiquitous language) and the solution will come naturally. #

Upvotes: 3

Enno Shioji
Enno Shioji

Reputation: 26882

EDIT: Oh wait, I see it's nested.. You could still go for a look-up solution. Instead of Map<String, Integer>, you could use something like Map<Map<String,Boolean>, Integer> where the Integer is the final score.


This is one common way to do it:

Map<String, Integer> choice_delta = // new Map

// Define choice delta pairing
choice_delta.put("answer5", -5);
choice_delta.put("answer6", 20);
// etc. etc.

int calculate(String[] answers){
    int result = 0;
    for (String answer : answers){
        int delta = choice_delta.get(answer);
        result += delta;
    }
    return result;
}

Upvotes: 3

Hot Licks
Hot Licks

Reputation: 47699

Generally, if one goes beyond maybe 4-5 categories, I'll invent some sort of table-driven approach. Precisely what would depend on the details (and my mood), but Enno's is a good one, and typical of the concept.

Upvotes: 0

Related Questions