Opening a tip before answering is a nudge. The answer that follows is still right — it is counted as right, and the percentage is not docked — but it is not the same as right, so it keeps its own arc on the donut and its own line in the legend: "3 correct after a tip". attempt_answers.used_hint records it. The player reports which questions had a tip opened before the answer went in; a tip read afterwards is revision and does not count, which is the difference two of the tests turn on. Both endings agree about it — an explicit submit carries the list, and an exam that runs out takes it from the saved progress, so a tab closing cannot launder a score. Found while wiring this: RichText declared its component overrides inline in the render, so every one was a fresh component type and React remounted the whole rendered tree on each render. An open tip closed itself every time the exam clock ticked. The map is memoised now. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TqXevQJhxFrM7jJg82cgZN
28 lines
786 B
Python
28 lines
786 B
Python
"""Record whether a tip was opened before the question was answered.
|
|
|
|
Getting an answer right after reading a nudge is not the same as getting it
|
|
right, and neither is it wrong. Kept as its own fact so the analysis can say
|
|
which it was rather than folding one into the other.
|
|
|
|
Rows written before tips existed take 0. That is not a guess: there was
|
|
nothing to open.
|
|
|
|
Revision ID: e1f2a3b4c5d6
|
|
Revises: d0e1f2a3b4c5
|
|
"""
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
revision = "e1f2a3b4c5d6"
|
|
down_revision = "d0e1f2a3b4c5"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.add_column("attempt_answers", sa.Column(
|
|
"used_hint", sa.Boolean(), nullable=False, server_default="0"))
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_column("attempt_answers", "used_hint")
|