6

I have to create reports based on the user input. User answer a question, and then depending on the answer I go left or right in a treelike structure, and ask a new question. Some nodes will have the same question, but different children. I am not sure what would be the best way to do it in terms of code readability?

I would like to avoid huge control structure, as it would be extremely unreadable, like this:

if() {
    if() {
        if() {
            if() {
                ... 
            }
        }
        else {
            if() {
                ...
            }
        }
    }
    else {
        ...
    }
}
else {
    if() {
        if() {
            if() {
                ...
            }
        }
        else {
            if () {
                ...
            }
        }
    }
}

Is there some better way to deal with it? Here is an image of how my tree looks like

enter image description here

Marko D
  • 7,576
  • 2
  • 26
  • 38
  • I think it cannot be optimized anymore because control structure is the very basic part of a language, if your logic is very complicated then your program must also be complicated. Yet you can combine the parent conditions with descendant conditions using `&&` to make the control structure 'plainer', e.g.`if(COND1 && COND2){}if(COND1 && COND3){} ...` thus there will be less nesting – dotslashlu Mar 14 '13 at 22:22

2 Answers2

2

If you are using mysql then simply have a table for questions and a table for answers like so:

Question Table:

+----------+-----------+
| id       | question  |
+----------+-----------+
| 1        | Question 1|
+----------+-----------+
| 2        | Question 2|
+----------+-----------+
| 3        | Question 3|
+----------+-----------+

Answers Table:

+----------+-----------+-----------+---------------+
| id       | answer    | question  | next_question |
+----------+-----------+-----------+---------------+
| 1        | Answer 1  | 1         | 2             |
+----------+-----------+-----------+---------------+ 
| 2        | Answer 2  | 1         | 3             | 
+----------+-----------+-----------+---------------+

If the user is on question 1 and selects the first answer, they go to question 2. If they select the second answer they go to question 3.

So in your code just query the database after every answer using the id:

SELECT next_question FROM answers WHERE id = ?; // Change '?' depending on answer to get next question

Then get the next answers like so:

SELECT answer FROM answers WHERE question = ?; // Change '?' depending on previous value retrieved

Hope that helps.

JWMarchant
  • 356
  • 2
  • 8
  • thanks a lot for your answer, it helped me to get on the right track! i didn't use mysql, but i used your idea to make something like @SpacedMonkey suggested in his answer! +1 – Marko D Mar 15 '13 at 16:35
2

Store the tree as data and then your code can be really quite small. If we modify the answer given by @jam6549 a little we can come up with something like this:

var answer = [ {t: "Does it have fur?", y: 1,  n: 2},
               {t: "Is it a kitten?",   y: 3,  n: 4},
               {t: "Is it a goldfish?", y: 5,  n: 4},
               {t: "Found a kitten",    y: -1, n: -1},
               {t: "I'm stumped",       y: -1, n: -1},
               {t: "Found a goldfish",  y: -1, n: -1} ];
var state = 0;

while ( answer[state].y >= 0 ) {
    var choice = confirm(answer[state].t);
    state = choice? answer[state].y: answer[state].n;
}
alert(answer[state].t);

This only supports simple y/n answers so I could use confirm, you'll want to use an array with an entry for each possible answer.

You say some of the questions are repeated so I'd be tempted to have an array with each unique question text. Then your answer array stores an index into the question array to save duplicating text.

SpacedMonkey
  • 2,725
  • 1
  • 16
  • 17
  • thanks for your answer, i started doing something like that, after @jam6549 gave me an idea with his answer! it's a little bit more complicated, since answers are not simple yes or no, it can be to enter date and then check if it's greater than some specific one etc, but it's definitely a good approach! i also made an array with each unique question not to repeat them as you suggested! thanks again! – Marko D Mar 15 '13 at 16:39