Introduction
Build a playable local quiz whose answers remain correct when choices move. You need Python functions, lists, dictionaries, conditions and loops. JSON, random selection and input validation are explained here. The prepared terminal engine handles presentation and feedback; you implement three rules in logic.py.
Use the WebIDE Terminal menu, then New Terminal (under More on narrow windows). All commands run in that terminal. Keep engine.py, quiz.py, demo.py and bank.json unchanged. Only logic.py is an editing target. Estimated reading and practice time: 40 minutes; not a measured beginner time.
Select Questions and Move Whole Options
In this step, play two known questions, then add random selection without losing identities. In the WebIDE terminal, cd changes the working directory; python3 runs a Python file.
cd /home/labex/project
python3 demo.py
Enter 1 for Sun, then 2 for Moon. Both show Correct!. This fixed-order demonstration is prepared; your reusable quiz will also move choices.
cat displays a text file:
cat bank.json
JSON represents lists with [], dictionaries with {}, and strings with double quotes. Each question has a question_id, a prompt, options and correct_option_id. Each option pairs option_id with text. IDs are stable; screen numbers are positions. Both sky and tide offer Sun/Moon, but Sun is correct only for sky. Option IDs are unique within a question, so identity is the question and option pair. Question IDs and texts within each question are unique in these supplied banks.
rng is a supplied random-generator object. Its sample(items, count) returns a new list without repeating an item; it does not repair duplicate question IDs. shuffle(items) moves a list in place, so copy the options first. Move whole dictionaries to keep each ID attached to its text. A requested count is positive; take at most the bank size using min(count, len(questions)). Randomness varies gameplay, not security. Equivalent sampling/shuffling is welcome; no fixed seed or order is required.
The following here-document writes Python text: > replaces logic.py; quoted <<'PY' keeps its contents literal until the final PY. Run the entire block, including that final line. It replaces the starter with these two functions; the input function comes next.
cat > logic.py <<'PY'
def choose_questions(questions, count, rng):
return rng.sample(questions, min(count, len(questions)))
def move_options(question, rng):
options = question["options"].copy()
rng.shuffle(options)
return options
PY
choose_questions now returns a bounded selection; move_options returns reordered option objects without modifying the bank. If the terminal shows a continuation prompt, finish the final PY on its own line.
Map a Valid Number Back to Its ID
In this step, translate a displayed choice into its stable option ID. The prepared engine passes ask (input) and tell (output) functions. ask returns text; strip() removes surrounding whitespace. enumerate(..., start=1) pairs each object with its displayed number. Compare text with str(position) so oops, -1, 0 and out-of-range numbers cannot submit. Only the displayed spelling is accepted: 1, not 01. q stops before submission. Return once for one valid answer; otherwise the while loop asks again.
In the same terminal, >> appends this function without replacing the two already written:
cat >> logic.py <<'PY'
def read_answer(options, ask, tell):
while True:
text = ask("Answer (number or q): ").strip()
if text.lower() == "q":
return None
for position, option in enumerate(options, start=1):
if text == str(position):
return option["option_id"]
tell("Enter one displayed number, or q to stop.")
PY
Play all available questions. --count requests a positive maximum; 100 still selects only the three supplied questions. Without --ordered, question and option positions vary.
python3 quiz.py bank.json --count 100
At the first prompt, try oops, -1, 0 and 99. Each shows Enter one displayed number, or q to stop. and repeats the same question. Then answer every question by its text: Sun for the star, Moon for tides, Root for soil water. Read the displayed number each time. Feedback must match your choice; the final result is:
Score: 3/3 answered
Run a shorter round and enter q immediately:
python3 quiz.py bank.json --count 2
Score: 0/0 answered
Unanswered questions are absent, not wrong. The prepared engine submits once, renders feedback from the current question/option relation, and calculates score. It does not store screen numbers. If you mistype a filename, Quiz error: ... and a nonzero exit mean no successful game; use ls to see names and rerun the exact command above. If Python reports a syntax error, repeat the corresponding complete here-document; do not reset the environment.
Summary
You built a reusable playable quiz with finite random selection and stable answer mapping. No records are saved in this unit.



