Skip to content

Commit ba02b78

Browse files
committed
fix: respect quiz format when selecting questions
1 parent 3185b3d commit ba02b78

File tree

2 files changed

+33
-21
lines changed

2 files changed

+33
-21
lines changed

data/quiz-bank.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@
714714
"hint": "Think of it as a digital ID badge that's been stamped by the server."
715715
},
716716
{
717-
"belt": "purple",
717+
"belt": "brown",
718718
"format": "free_response",
719719
"question": "Explain why you should never store passwords in plain text. What is 'hashing' and why is it preferred?",
720720
"expected_understanding": "Hashing is a one-way function that converts passwords into fixed-length strings. You can't reverse a hash back to the password. When a user logs in, you hash their input and compare hashes. If the database is breached, attackers see hashes, not passwords. Bcrypt adds 'salt' for extra security.",
@@ -885,7 +885,7 @@
885885
"hint": "Think of an assembly line where each station checks something before passing it along."
886886
},
887887
{
888-
"belt": "purple",
888+
"belt": "brown",
889889
"format": "free_response",
890890
"question": "Explain the difference between Continuous Delivery and Continuous Deployment. Why might a team choose one over the other?",
891891
"expected_understanding": "Continuous Delivery means code is always ready to deploy but requires manual approval for production. Continuous Deployment means every change that passes tests is automatically deployed. Teams handling sensitive data (banking, healthcare) may prefer Delivery for the manual gate, while fast-moving startups may prefer full Deployment.",
@@ -920,15 +920,15 @@
920920
"hint": "Think of them as 'recipes' that experienced developers have already figured out."
921921
},
922922
{
923-
"belt": "purple",
923+
"belt": "brown",
924924
"question": "What is the Observer pattern and where might you see it in everyday web development?",
925925
"options": ["A pattern for watching files for changes", "A pattern where objects subscribe to events and get notified when something changes", "A pattern for monitoring server performance"],
926926
"correct": 1,
927927
"explanation": "The Observer pattern lets objects 'subscribe' to events and react when they happen. You use it constantly in web dev: addEventListener in the DOM, React's state/re-render system, Redux subscriptions, and WebSocket message handlers are all variations of Observer.",
928928
"hint": "Think about event listeners and how multiple parts of your app react to changes."
929929
},
930930
{
931-
"belt": "purple",
931+
"belt": "brown",
932932
"format": "free_response",
933933
"question": "Explain the Singleton pattern. What problem does it solve, and what are its potential drawbacks?",
934934
"expected_understanding": "Singleton ensures a class has only one instance (like a database connection pool or config manager). It solves the problem of accidental duplicate instances of shared resources. Drawbacks: it's essentially a global variable (hard to test, tight coupling), can hide dependencies, and makes parallel testing difficult.",
@@ -945,15 +945,15 @@
945945
"hint": "Think 'scale up' (bigger) versus 'scale out' (more)."
946946
},
947947
{
948-
"belt": "purple",
948+
"belt": "brown",
949949
"question": "What is a CDN and how does it improve scalability?",
950950
"options": ["A type of database", "A network of servers worldwide that caches content close to users", "A programming framework"],
951951
"correct": 1,
952952
"explanation": "A CDN (Content Delivery Network) copies your static files (images, CSS, JS) to servers around the world. Users get served from the nearest location, reducing load time. It also takes traffic load off your origin server, improving scalability.",
953953
"hint": "It's about putting copies of your content closer to where your users are."
954954
},
955955
{
956-
"belt": "purple",
956+
"belt": "brown",
957957
"format": "free_response",
958958
"question": "Explain what 'caching' means in web development and describe two different levels where caching can occur.",
959959
"expected_understanding": "Caching stores frequently requested data in a faster location to avoid recomputing or refetching it. Browser cache (stores assets locally), CDN cache (stores content at edge servers), server-side cache like Redis (stores database query results in memory), and database query cache are common levels. Each level trades freshness for speed.",

scripts/quiz-selector.sh

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,30 @@ QUIZ_BANK="$PLUGIN_ROOT/data/quiz-bank.json"
2222
# Default output if we can't determine anything
2323
DEFAULT_OUTPUT='{"mode":"dynamic","concept":null,"reason":"No profile data available","static_question":null,"belt":"white","quiz_format":"multiple_choice"}'
2424

25+
select_static_question() {
26+
local concept="$1"
27+
28+
jq -c \
29+
--arg concept "$concept" \
30+
--arg belt "$BELT" \
31+
--arg format "$QUIZ_FORMAT" '
32+
def rank($value):
33+
if $value == "white" then 0
34+
elif $value == "yellow" then 1
35+
elif $value == "orange" then 2
36+
elif $value == "green" then 3
37+
elif $value == "blue" then 4
38+
elif $value == "brown" then 5
39+
elif $value == "black" then 6
40+
else -1
41+
end;
42+
(.quizzes[$concept] // []) as $questions |
43+
(($questions | map(select(rank(.belt) >= 0 and rank(.belt) <= rank($belt) and ((.format // "multiple_choice") == $format))) | first) //
44+
($questions | map(select(rank(.belt) >= 0 and rank(.belt) <= rank($belt))) | first) //
45+
null)
46+
' "$QUIZ_BANK"
47+
}
48+
2549
if ! command -v jq &> /dev/null; then
2650
echo "$DEFAULT_OUTPUT"
2751
exit 0
@@ -114,11 +138,7 @@ fi
114138

115139
# If spaced repetition found a concept, check for a static question
116140
if [ -n "$SPACED_REP_CONCEPT" ] && [ -f "$QUIZ_BANK" ]; then
117-
STATIC_Q=$(jq -c --arg concept "$SPACED_REP_CONCEPT" --arg belt "$BELT" '
118-
.quizzes[$concept] // [] |
119-
map(select(.belt == $belt or .belt == "white")) |
120-
first // null
121-
' "$QUIZ_BANK")
141+
STATIC_Q=$(select_static_question "$SPACED_REP_CONCEPT")
122142

123143
if [ "$STATIC_Q" != "null" ] && [ -n "$STATIC_Q" ]; then
124144
echo "{\"mode\":\"spaced_repetition\",\"concept\":\"$SPACED_REP_CONCEPT\",\"reason\":\"$SPACED_REP_REASON\",\"static_question\":$STATIC_Q,\"belt\":\"$BELT\",\"quiz_format\":\"$QUIZ_FORMAT\"}"
@@ -143,11 +163,7 @@ if [ "$SESSION_CONCEPTS" != "[]" ]; then
143163
fi
144164

145165
if [ -n "$UNQUIZZED_CONCEPT" ] && [ -f "$QUIZ_BANK" ]; then
146-
STATIC_Q=$(jq -c --arg concept "$UNQUIZZED_CONCEPT" --arg belt "$BELT" '
147-
.quizzes[$concept] // [] |
148-
map(select(.belt == $belt or .belt == "white")) |
149-
first // null
150-
' "$QUIZ_BANK")
166+
STATIC_Q=$(select_static_question "$UNQUIZZED_CONCEPT")
151167

152168
if [ "$STATIC_Q" != "null" ] && [ -n "$STATIC_Q" ]; then
153169
echo "{\"mode\":\"static\",\"concept\":\"$UNQUIZZED_CONCEPT\",\"reason\":\"New concept from this session — not yet quizzed.\",\"static_question\":$STATIC_Q,\"belt\":\"$BELT\",\"quiz_format\":\"$QUIZ_FORMAT\"}"
@@ -170,11 +186,7 @@ if [ "$CONCEPTS_SEEN" != "[]" ]; then
170186
fi
171187

172188
if [ -n "$LEAST_QUIZZED" ] && [ "$LEAST_QUIZZED" != "null" ] && [ -f "$QUIZ_BANK" ]; then
173-
STATIC_Q=$(jq -c --arg concept "$LEAST_QUIZZED" --arg belt "$BELT" '
174-
.quizzes[$concept] // [] |
175-
map(select(.belt == $belt or .belt == "white")) |
176-
first // null
177-
' "$QUIZ_BANK")
189+
STATIC_Q=$(select_static_question "$LEAST_QUIZZED")
178190

179191
echo "{\"mode\":\"static\",\"concept\":\"$LEAST_QUIZZED\",\"reason\":\"Reinforcing least-practiced concept.\",\"static_question\":$STATIC_Q,\"belt\":\"$BELT\",\"quiz_format\":\"$QUIZ_FORMAT\"}"
180192
exit 0

0 commit comments

Comments
 (0)