QuizGenerator 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. quizgenerator-0.3.0/.envrc +3 -0
  2. quizgenerator-0.3.0/.github/pull_request_template.md +36 -0
  3. quizgenerator-0.3.0/.github/workflows/release.yaml +149 -0
  4. quizgenerator-0.3.0/.gitignore +13 -0
  5. quizgenerator-0.3.0/CLAUDE.md +80 -0
  6. quizgenerator-0.3.0/CODEOWNERS +1 -0
  7. quizgenerator-0.3.0/LICENSE +674 -0
  8. quizgenerator-0.3.0/PKG-INFO +265 -0
  9. quizgenerator-0.3.0/QuizGenerator/README.md +5 -0
  10. quizgenerator-0.3.0/QuizGenerator/__init__.py +27 -0
  11. quizgenerator-0.3.0/QuizGenerator/__main__.py +7 -0
  12. quizgenerator-0.3.0/QuizGenerator/canvas/__init__.py +13 -0
  13. quizgenerator-0.3.0/QuizGenerator/canvas/canvas_interface.py +627 -0
  14. quizgenerator-0.3.0/QuizGenerator/canvas/classes.py +235 -0
  15. quizgenerator-0.3.0/QuizGenerator/constants.py +149 -0
  16. quizgenerator-0.3.0/QuizGenerator/contentast.py +1955 -0
  17. quizgenerator-0.3.0/QuizGenerator/generate.py +253 -0
  18. quizgenerator-0.3.0/QuizGenerator/logging.yaml +55 -0
  19. quizgenerator-0.3.0/QuizGenerator/misc.py +579 -0
  20. quizgenerator-0.3.0/QuizGenerator/mixins.py +548 -0
  21. quizgenerator-0.3.0/QuizGenerator/performance.py +202 -0
  22. quizgenerator-0.3.0/QuizGenerator/premade_questions/__init__.py +0 -0
  23. quizgenerator-0.3.0/QuizGenerator/premade_questions/basic.py +103 -0
  24. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst334/__init__.py +1 -0
  25. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst334/languages.py +395 -0
  26. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst334/math_questions.py +297 -0
  27. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst334/memory_questions.py +1400 -0
  28. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst334/ostep13_vsfs.py +572 -0
  29. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst334/persistence_questions.py +396 -0
  30. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst334/process.py +648 -0
  31. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/__init__.py +0 -0
  32. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/gradient_descent/__init__.py +3 -0
  33. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/gradient_descent/gradient_calculation.py +369 -0
  34. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/gradient_descent/gradient_descent_questions.py +305 -0
  35. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/gradient_descent/loss_calculations.py +650 -0
  36. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/gradient_descent/misc.py +73 -0
  37. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/math_and_data/__init__.py +2 -0
  38. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/math_and_data/matrix_questions.py +631 -0
  39. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/math_and_data/vector_questions.py +534 -0
  40. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/models/__init__.py +0 -0
  41. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/models/attention.py +192 -0
  42. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/models/cnns.py +186 -0
  43. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/models/matrices.py +24 -0
  44. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/models/rnns.py +202 -0
  45. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/models/text.py +201 -0
  46. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/models/weight_counting.py +227 -0
  47. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/neural-network-basics/__init__.py +6 -0
  48. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/neural-network-basics/neural_network_questions.py +1308 -0
  49. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/tensorflow-intro/__init__.py +6 -0
  50. quizgenerator-0.3.0/QuizGenerator/premade_questions/cst463/tensorflow-intro/tensorflow_questions.py +936 -0
  51. quizgenerator-0.3.0/QuizGenerator/qrcode_generator.py +293 -0
  52. quizgenerator-0.3.0/QuizGenerator/question.py +676 -0
  53. quizgenerator-0.3.0/QuizGenerator/quiz.py +467 -0
  54. quizgenerator-0.3.0/QuizGenerator/typst_utils.py +113 -0
  55. quizgenerator-0.3.0/README.md +225 -0
  56. quizgenerator-0.3.0/documentation/GRADING_GUIDE.md +284 -0
  57. quizgenerator-0.3.0/documentation/LESSONS_LEARNED-adding_questions.md +707 -0
  58. quizgenerator-0.3.0/documentation/PARAMETER_STANDARDS.md +111 -0
  59. quizgenerator-0.3.0/documentation/README.md +158 -0
  60. quizgenerator-0.3.0/documentation/WEB_UI_INTEGRATION.md +446 -0
  61. quizgenerator-0.3.0/example_files/all_classes.yaml +184 -0
  62. quizgenerator-0.3.0/example_files/cst334.yaml +173 -0
  63. quizgenerator-0.3.0/example_files/cst463.yaml +199 -0
  64. quizgenerator-0.3.0/example_files/exam_generation.yaml +41 -0
  65. quizgenerator-0.3.0/example_files/scratch.yaml +72 -0
  66. quizgenerator-0.3.0/example_files/specific_generators/cst334.caching.yaml +32 -0
  67. quizgenerator-0.3.0/example_files/specific_generators/cst334.lab-address_translation.yaml +19 -0
  68. quizgenerator-0.3.0/examples/README.md +55 -0
  69. quizgenerator-0.3.0/examples/web_ui_integration_example.py +207 -0
  70. quizgenerator-0.3.0/grade_from_qr.py +472 -0
  71. quizgenerator-0.3.0/pyproject.toml +75 -0
  72. quizgenerator-0.3.0/pyproject_prev.toml +75 -0
  73. quizgenerator-0.3.0/scripts/generate_practice_yaml.sh +17 -0
  74. quizgenerator-0.3.0/scripts/print.sh +24 -0
  75. quizgenerator-0.3.0/scripts/vendor_lms_interface.py +335 -0
  76. quizgenerator-0.3.0/uv.lock +1567 -0
@@ -0,0 +1,3 @@
1
+ #!env zsh
2
+
3
+ source .venv/bin/activate
@@ -0,0 +1,36 @@
1
+ # Pull Request
2
+
3
+ ## Description
4
+ <!-- Provide a brief description of what this PR accomplishes -->
5
+
6
+ ## Changes Made
7
+ <!-- List the key changes made in this PR -->
8
+ -
9
+ -
10
+ -
11
+
12
+ ## Type of Change
13
+ <!-- Mark the appropriate option with an [x] -->
14
+ - [ ] Bug fix (non-breaking change that fixes an issue)
15
+ - [ ] New feature (non-breaking change that adds functionality)
16
+ - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
17
+ - [ ] Documentation update
18
+ - [ ] Refactoring (no functional changes)
19
+
20
+ ## Testing Done
21
+ <!-- Describe the testing you've done to verify your changes -->
22
+
23
+ ## Checklist
24
+ <!-- Mark the appropriate options with an [x] -->
25
+ - [ ] My code follows the style guidelines of this project
26
+ - [ ] I have performed a self-review of my own code
27
+ - [ ] I have commented my code, particularly in hard-to-understand areas
28
+ - [ ] I have updated the documentation accordingly
29
+ - [ ] My changes generate no new warnings
30
+ - [ ] Any dependent changes have been merged and published
31
+
32
+ ## Screenshots (if applicable)
33
+ <!-- Add screenshots here if they help explain your changes -->
34
+
35
+ ## Notes
36
+ <!-- Any additional notes or context about the PR -->
@@ -0,0 +1,149 @@
1
+ name: Release on version bump
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main # change if your default branch is different
7
+
8
+ jobs:
9
+ release:
10
+ runs-on: ubuntu-latest
11
+ environment:
12
+ name: pypi
13
+ permissions:
14
+ contents: write # create tags & releases
15
+ id-token: write # PyPI trusted publishing
16
+
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@v5
20
+ with:
21
+ fetch-depth: 0 # need history to read previous version
22
+
23
+ - name: Set up Python for tooling
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version: "3.12"
27
+
28
+ - name: Get previous version (from parent commit)
29
+ id: prev_version
30
+ run: |
31
+ BEFORE="${{ github.event.before }}"
32
+
33
+ # First commit / no parent? treat as "no previous version"
34
+ if [ "$BEFORE" = "0000000000000000000000000000000000000000" ] || [ -z "$BEFORE" ]; then
35
+ echo "No previous commit; setting previous version empty."
36
+ echo "version=" >> "$GITHUB_OUTPUT"
37
+ else
38
+ if git show "$BEFORE":pyproject.toml > pyproject_prev.toml 2>/dev/null; then
39
+ VERSION=$(python -c "import tomllib, pathlib; d = tomllib.loads(pathlib.Path('pyproject_prev.toml').read_text()); print(d['project']['version'])")
40
+ echo "previous version: $VERSION"
41
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
42
+ else
43
+ echo "No previous pyproject.toml found; setting previous version empty."
44
+ echo "version=" >> "$GITHUB_OUTPUT"
45
+ fi
46
+ fi
47
+
48
+ - name: Get current version
49
+ id: curr_version
50
+ run: |
51
+ VERSION=$(python -c "import tomllib, pathlib; d = tomllib.loads(pathlib.Path('pyproject.toml').read_text()); print(d['project']['version'])")
52
+ echo "current version: $VERSION"
53
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
54
+
55
+ - name: Decide whether this is a release commit
56
+ id: decision
57
+ run: |
58
+ PREV="${{ steps.prev_version.outputs.version }}"
59
+ CURR="${{ steps.curr_version.outputs.version }}"
60
+ MSG="${{ github.event.head_commit.message }}"
61
+
62
+ echo "Previous version: '$PREV'"
63
+ echo "Current version: '$CURR'"
64
+ echo "Commit message: '$MSG'"
65
+
66
+ SHOULD_RELEASE=false
67
+
68
+ # Require version change AND 'release' in the commit message
69
+ if [ -n "$CURR" ] && [ "$CURR" != "$PREV" ]; then
70
+ if echo "$MSG" | grep -qi "release"; then
71
+ echo "Version changed and commit message indicates release."
72
+ SHOULD_RELEASE=true
73
+ else
74
+ echo "Version changed but commit message does not contain 'release'; not releasing."
75
+ fi
76
+ else
77
+ echo "Version did not change; not releasing."
78
+ fi
79
+
80
+ echo "release=$SHOULD_RELEASE" >> "$GITHUB_OUTPUT"
81
+
82
+ - name: Stop if not a release
83
+ if: steps.decision.outputs.release != 'true'
84
+ run: |
85
+ echo "Not a release commit; skipping remaining steps."
86
+ exit 0
87
+
88
+ - name: Ensure tag does not already exist
89
+ if: steps.decision.outputs.release == 'true'
90
+ run: |
91
+ VERSION="${{ steps.curr_version.outputs.version }}"
92
+ TAG="v${VERSION}"
93
+
94
+ echo "Checking for existing tag $TAG"
95
+ if git rev-parse "$TAG" >/dev/null 2>&1; then
96
+ echo "Tag $TAG already exists. Aborting."
97
+ exit 1
98
+ fi
99
+
100
+ - name: Create and push tag
101
+ if: steps.decision.outputs.release == 'true'
102
+ run: |
103
+ VERSION="${{ steps.curr_version.outputs.version }}"
104
+ TAG="v${VERSION}"
105
+
106
+ echo "Creating tag $TAG at $GITHUB_SHA"
107
+
108
+ git config user.name "github-actions[bot]"
109
+ git config user.email "github-actions[bot]@users.noreply.github.com"
110
+
111
+ git tag "$TAG" "$GITHUB_SHA"
112
+ git push origin "$TAG"
113
+
114
+ - name: Install uv
115
+ if: steps.decision.outputs.release == 'true'
116
+ uses: astral-sh/setup-uv@v6
117
+
118
+ - name: Install Python 3.13 for build
119
+ if: steps.decision.outputs.release == 'true'
120
+ run: uv python install 3.13
121
+
122
+ - name: Build
123
+ if: steps.decision.outputs.release == 'true'
124
+ run: uv build
125
+
126
+ - name: Upload dist artifacts
127
+ if: steps.decision.outputs.release == 'true'
128
+ uses: actions/upload-artifact@v4
129
+ with:
130
+ name: dist
131
+ path: dist/
132
+
133
+ - name: Publish to PyPI
134
+ if: steps.decision.outputs.release == 'true'
135
+ run: uv publish
136
+
137
+ - name: Create GitHub Release
138
+ if: steps.decision.outputs.release == 'true'
139
+ uses: softprops/action-gh-release@v2
140
+ with:
141
+ tag_name: v${{ steps.curr_version.outputs.version }}
142
+ name: v${{ steps.curr_version.outputs.version }}
143
+ body: |
144
+ Release v${{ steps.curr_version.outputs.version }}
145
+
146
+ - Version bumped in pyproject.toml
147
+ - Built with uv and published to PyPI.
148
+ - Artifacts attached below.
149
+ files: dist/*
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ exam.pdf
3
+ out/
4
+ .idea/
5
+ .DS_Store
6
+ *.zip
7
+ .env
8
+ output.csv
9
+ imgs/
10
+ debug.*
11
+ .claude
12
+ *.log
13
+ dist/
@@ -0,0 +1,80 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ This is a Python-based teaching tools project focused on quiz generation and Canvas LMS integration. The main entry point is `generate_quiz.py`, which generates quizzes in both PDF format and Canvas variations based on YAML configuration files.
8
+
9
+ ## Architecture
10
+
11
+ ### Core Modules
12
+ - **QuizGenerator/**: Main quiz generation engine
13
+ - `quiz.py`: Core Quiz class that loads from YAML and generates output
14
+ - `question.py`: Question classes and registry system for different question types
15
+ - `premade_questions/`: Collection of specialized question generators (memory, processes, persistence, etc.)
16
+ - `misc.py`: Utilities for output formats and content handling
17
+
18
+ - **lms_interface/**: Canvas LMS integration (submodule)
19
+ - `canvas_interface.py`: CanvasInterface and CanvasCourse classes for API interaction
20
+ - `classes.py`: Data models for LMS objects
21
+
22
+ ### Question System
23
+ The project uses a plugin-based question system where question types are defined as classes in `premade_questions/` and registered dynamically. Questions are defined in YAML files that specify the class name and parameters.
24
+
25
+ ### Configuration Files
26
+ Quiz configurations are stored in `example_files/` as YAML files. The default configuration is `exam_generation.yaml`, which defines question types, point values, and organization.
27
+
28
+ ## Development Commands
29
+
30
+ ### Environment Setup
31
+ ```bash
32
+ # The project uses uv for dependency management
33
+ uv sync
34
+ source .venv/bin/activate
35
+ ```
36
+
37
+ ### Running the Main Script
38
+ ```bash
39
+ # Generate PDFs only
40
+ python generate_quiz.py --num_pdfs 3
41
+
42
+ # Generate Canvas quizzes (requires course_id)
43
+ python generate_quiz.py --num_canvas 5 --course_id 12345
44
+
45
+ # Use production Canvas instance
46
+ python generate_quiz.py --prod --num_canvas 2 --course_id 12345
47
+
48
+ # Custom quiz configuration
49
+ python generate_quiz.py --quiz_yaml example_files/custom_quiz.yaml --num_pdfs 2
50
+ ```
51
+
52
+ ### Quality Tools
53
+ The project includes development dependencies for code quality:
54
+ ```bash
55
+ # Code formatting
56
+ black .
57
+
58
+ # Linting
59
+ flake8
60
+
61
+ # Type checking
62
+ mypy QuizGenerator/
63
+
64
+ # Testing
65
+ pytest
66
+ ```
67
+
68
+ ### LaTeX Dependencies
69
+ PDF generation requires LaTeX with `latexmk`. Generated PDFs are output to the `out/` directory.
70
+
71
+ ## Key Files and Patterns
72
+
73
+ - Quiz configurations follow the pattern in `example_files/exam_generation.yaml`
74
+ - New question types should extend base classes in `question.py` and be placed in `premade_questions/`
75
+ - The project uses logging extensively - check `teachingtools.log` for detailed output
76
+ - Canvas integration requires environment variables for API keys (see `.env` symlink)
77
+
78
+ ## Testing Notes
79
+
80
+ The project includes a test mode accessible via `python generate_quiz.py TEST`.
@@ -0,0 +1 @@
1
+ * @samogden