Skip to content

TOHgoto/quizkit

Repository files navigation

QuizKit

A markdown-driven, self-hosted quiz platform powered by Streamlit + SQLite. Turn any markdown content into an interactive quiz — lectures, notes, documentation, or anything you want to master.

Stack

  • Python
  • Streamlit (Web UI)
  • SQLite (local database)

Project Purpose

QuizKit is a local-first quiz system for turning markdown lecture notes into a reusable question bank, then using that bank for exam generation, review, wrong-question practice, and optional LLM-assisted study workflows.

Core responsibilities:

  • UI: Streamlit pages for exam generation, answering, review, stats, and wrongbook practice
  • Application: quiz indexing, exam generation, scoring, history/statistics, and LLM workflows
  • Domain: markdown quiz parsing and question normalization
  • Infrastructure: SQLite schema/bootstrap and external LLM provider access

Structure

quizkit/
├── app.py                     # Thin Streamlit entrypoint
├── quizkit/
│   ├── config.py             # App configuration loading
│   ├── application/
│   │   ├── quiz_service.py   # Quiz indexing/exam/history/statistics services
│   │   ├── llm_service.py    # LLM workflows, cache, audit, draft operations
│   │   └── services.py       # Compatibility re-export layer
│   ├── domain/
│   │   └── parser.py         # Markdown question parsing
│   ├── infrastructure/
│   │   ├── db.py             # SQLite schema and migrations bootstrap
│   │   └── llm_client.py     # LLM provider adapters
│   └── ui/
│       ├── streamlit_app.py  # Streamlit app bootstrap and route dispatch
│       ├── context.py        # UI shared context object (cfg + db conn)
│       ├── state.py          # Session state bootstrap and page navigation
│       ├── helpers.py        # Shared UI helper functions
│       └── pages/
│           ├── home_page.py
│           ├── exam_page.py
│           ├── result_page.py
│           ├── history_page.py
│           ├── stats_page.py
│           └── wrongbook_page.py
├── migrations/
│   └── migrate.py
├── config.yaml
├── config.example.yaml
└── data/

Rule of thumb:

  • Keep runnable entry scripts in the repository root.
  • Put business logic under quizkit/application.
  • Put parsing or pure rules under quizkit/domain.
  • Put database and external service adapters under quizkit/infrastructure.

Features

  • Reindex lecture markdown files into a local question bank
  • Generate exams by lecture range
  • Submit answers and auto-score
  • View per-question result and answer review
  • History of attempts
  • Stats by lecture and tag
  • Wrongbook and wrong-question practice mode
  • Question type labels (True/False, Single Choice)
  • Exam countdown timer
  • Quick select by lecture number (Lecture1-Lecture8)
  • CSV export for history and stats
  • Database migration script for schema upgrades

Defaults

  • LECTURE_DIR: ../../blackboard/lectures/markdown
  • EXAM_QUESTION_COUNT: 20
  • EXAM_DURATION_MINUTES: 40
  • ALLOW_UNDERFILLED_EXAM: false
  • DB_PATH: ./data/app.db

YAML Config File

The app supports a YAML config file at config.yaml.

Priority order (high to low):

  1. Environment variables
  2. config.yaml
  3. Built-in defaults

Path policy:

  • Absolute paths are recommended.
  • Relative paths are allowed and will be resolved to absolute paths based on the config file directory.

You can set a custom config file path with:

export APP_CONFIG_FILE=/absolute/path/to/config.yaml

Use config.example.yaml as a template.

LLM Integration (Manual Trigger)

This version supports optional LLM integration for:

  • Question optimization (preview only, does not overwrite source markdown)
  • Missing explanation generation (writes to DB questions.explanation)
  • Study recommendation generation after an attempt

Built-in reliability features:

  • LLM response cache (prevents duplicate calls)
  • LLM audit logs (task status, cache hit, retries, latency, tokens)
  • One-click apply optimized output into question_drafts (requires UI confirmation)
  • Batch cap and item-level retry strategy

Supported providers:

  • openai_compatible (or openai)
  • anthropic

Enable in config.yaml:

llm:
  enabled: true
  provider: openai_compatible
  api_key: "YOUR_KEY"
  base_url: https://api.openai.com/v1
  model: gpt-4o-mini

Related environment variables (override YAML):

  • LLM_ENABLED
  • LLM_PROVIDER
  • LLM_API_KEY
  • LLM_BASE_URL
  • LLM_MODEL
  • LLM_TIMEOUT_SECONDS
  • LLM_MAX_RETRIES
  • LLM_TEMPERATURE
  • LLM_MAX_TOKENS
  • LLM_MAX_BATCH_ITEMS
  • LLM_ITEM_MAX_RETRIES
  • LLM_RETRY_BACKOFF_SECONDS
  • LLM_ENABLE_QUESTION_OPTIMIZATION
  • LLM_ENABLE_EXPLANATION_GENERATION
  • LLM_ENABLE_STUDY_RECOMMENDATION

Run

cd quizkit
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python3 -m streamlit run app.py

Migration

If you already have an old local DB and upgrade code, run:

python3 migrations/migrate.py

Notes

  • Current parser supports:
    • :::quiz blocks
    • legacy numbered quiz format from in-class_quiz.md
  • Questions are versioned by source hash to preserve attempt traceability.
  • Short-answer questions are indexed but excluded from MVP auto-graded exams.

About

Quiz toolkit with modular generation/grading/explanation pipelines and optional local LLM integration

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages