Skip to content

Commit fee6a90

Browse files
fix bug in displaying a single incorrect question after quiz
1 parent c5ba23c commit fee6a90

File tree

2 files changed

+125
-3
lines changed

2 files changed

+125
-3
lines changed

ā€Žindex.htmlā€Ž

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,10 @@ <h5>${t.term}</h5>
350350
const selected = new Map();
351351
const weights = questionPool.map(q => {
352352
const qId = q.question_number || q.id || 'N/A';
353-
return 1 / ((state.answerCounts[qId] || 0) + 1);
353+
// Higher weight for questions never answered or answered incorrectly
354+
const timesAnswered = state.answerCounts[qId] || 0;
355+
const timesIncorrect = state.attemptHistory[qId]?.filter(attempt => !attempt.is_correct)?.length || 0;
356+
return (1 + timesIncorrect) / (timesAnswered + 1);
354357
});
355358

356359
let totalWeight = weights.reduce((a, b) => a + b, 0);
@@ -662,11 +665,25 @@ <h6>Justifications:</h6>
662665
let incorrect = 0;
663666
const incorrectQuestions = [];
664667

668+
// Update state with results
665669
currentSession.forEach(q => {
666670
const qId = q.question_number || q.id || 'N/A';
667671
const userAns = currentSessionAnswers[qId];
668672
if (!userAns) return;
669673

674+
// Update answer counts
675+
state.answerCounts[qId] = (state.answerCounts[qId] || 0) + 1;
676+
677+
// Update attempt history
678+
if (!state.attemptHistory[qId]) {
679+
state.attemptHistory[qId] = [];
680+
}
681+
state.attemptHistory[qId].push({
682+
timestamp: Date.now(),
683+
answer: userAns.answer,
684+
is_correct: userAns.is_correct
685+
});
686+
670687
if (userAns.is_correct) {
671688
correct++;
672689
} else {
@@ -675,6 +692,9 @@ <h6>Justifications:</h6>
675692
}
676693
});
677694

695+
// Save state to localStorage
696+
localStorage.setItem('ctai_exam_state', JSON.stringify(state));
697+
678698
// Calculate time taken
679699
const timeTaken = state.sessionStartTime ? Math.floor((Date.now() - state.sessionStartTime) / 1000) : 0;
680700
const minutes = Math.floor(timeTaken / 60);
@@ -718,16 +738,21 @@ <h4>Result Summary</h4>
718738

719739
// Generate answers block
720740
let options = [];
721-
if (q.options) {
741+
if (q.options && Array.isArray(q.options)) {
722742
options = q.options.map((opt, idx) => ({
723743
key: String.fromCharCode(97 + idx),
724744
value: opt
725745
}));
726-
} else if (q.answers) {
746+
} else if (q.answers && typeof q.answers === 'object') {
727747
options = Object.entries(q.answers).map(([key, value]) => ({
728748
key: key.toLowerCase(),
729749
value: `${key}) ${value}`
730750
}));
751+
} else if (typeof q.options === 'object') {
752+
options = Object.entries(q.options).map(([key, value]) => ({
753+
key: key.toLowerCase(),
754+
value: `${key}) ${value}`
755+
}));
731756
}
732757

733758
// Add answers with correct/incorrect indicators

ā€Žrequirements.txtā€Ž

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
āœ… App Requirements – ISTQB CT-AI Study App
2+
1. 🧠 Quiz Session Features
3+
Start 20-question session (weighted random) prioritizing unseen questions
4+
5+
Start 40-question session (fully random)
6+
7+
Questions are displayed one at a time
8+
9+
Navigation: Next, Back, and Submit buttons
10+
11+
Cannot proceed without selecting at least one answer
12+
13+
Submit button visible only on the last question
14+
15+
Back button hidden on first question
16+
17+
2. āœ… Answer Handling
18+
Support single and multiple correct answers
19+
20+
Track answers per question: selected, correctness
21+
22+
Accept multiple choice if correct_answer is an array
23+
24+
Calculate score only if all correct answers are selected
25+
26+
Save:
27+
28+
userAnswers → selected answer(s)
29+
30+
is_correct → whether the answer(s) are correct
31+
32+
answerCounts → number of times each question is answered
33+
34+
attemptHistory → history of attempted answers
35+
36+
3. šŸ“Š Result Evaluation
37+
Display summary:
38+
39+
āœ… Number of correct
40+
41+
āŒ Number of incorrect
42+
43+
šŸ“Š Score in %
44+
45+
ā±ļø Time taken (minutes + seconds)
46+
47+
Show justification for all options (not just correct one)
48+
49+
Style correct answers and justifications in green bold
50+
51+
4. šŸ’¾ State Persistence
52+
Use localStorage to:
53+
54+
Store question bank and glossary
55+
56+
Track session state (answered questions, scores)
57+
58+
Automatically load state on page load
59+
60+
Automatically update state on submit
61+
62+
Button to clear all state and restart quiz
63+
64+
5. šŸ“– Review Mode
65+
Button to Review All Questions
66+
67+
View one question at a time (like quiz mode)
68+
69+
Pre-select and highlight correct answers only
70+
71+
Show full justification for each answer
72+
73+
Disable submission in review mode
74+
75+
6. šŸ“š Glossary Mode
76+
Button to enter Glossary
77+
78+
Load glossary terms from embedded JSON block
79+
80+
Display term, definition, and example
81+
82+
Search bar to filter terms by name
83+
84+
Glossary is stored in localStorage on first run
85+
86+
7. šŸ“Ž Technical Requirements
87+
Works offline via file://
88+
89+
No external server required
90+
91+
All data loaded from embedded <script type="application/json">
92+
93+
Uses Bootstrap 5 for layout/styling
94+
95+
No use of React/JSX — pure JS and HTML
96+
97+
Handles malformed question data (missing answers/justification)

0 commit comments

Comments
Ā (0)
⚔