iliasqc 0.1.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.
- iliasqc-0.1.0/LICENSE +21 -0
- iliasqc-0.1.0/PKG-INFO +283 -0
- iliasqc-0.1.0/README.md +260 -0
- iliasqc-0.1.0/pyproject.toml +80 -0
- iliasqc-0.1.0/setup.cfg +4 -0
- iliasqc-0.1.0/src/iliasqc/__init__.py +57 -0
- iliasqc-0.1.0/src/iliasqc/cli.py +212 -0
- iliasqc-0.1.0/src/iliasqc/combine.py +362 -0
- iliasqc-0.1.0/src/iliasqc/convert.py +145 -0
- iliasqc-0.1.0/src/iliasqc/ilias.py +362 -0
- iliasqc-0.1.0/src/iliasqc/parser.py +248 -0
- iliasqc-0.1.0/src/iliasqc/qti.py +310 -0
- iliasqc-0.1.0/src/iliasqc/template.py +122 -0
- iliasqc-0.1.0/src/iliasqc.egg-info/PKG-INFO +283 -0
- iliasqc-0.1.0/src/iliasqc.egg-info/SOURCES.txt +24 -0
- iliasqc-0.1.0/src/iliasqc.egg-info/dependency_links.txt +1 -0
- iliasqc-0.1.0/src/iliasqc.egg-info/entry_points.txt +2 -0
- iliasqc-0.1.0/src/iliasqc.egg-info/requires.txt +5 -0
- iliasqc-0.1.0/src/iliasqc.egg-info/top_level.txt +1 -0
- iliasqc-0.1.0/tests/test_cli.py +136 -0
- iliasqc-0.1.0/tests/test_combine.py +312 -0
- iliasqc-0.1.0/tests/test_convert.py +177 -0
- iliasqc-0.1.0/tests/test_ilias.py +161 -0
- iliasqc-0.1.0/tests/test_parser.py +182 -0
- iliasqc-0.1.0/tests/test_qti.py +132 -0
- iliasqc-0.1.0/tests/test_template.py +43 -0
iliasqc-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Famke Bäuerle
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
iliasqc-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iliasqc
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python package to convert txt files into zip folder that can be uploaded to Ilias to create question pools.
|
|
5
|
+
Author: Famke Bäuerle
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/famosab/iliasqc
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/famosab/iliasqc/issues
|
|
9
|
+
Keywords: ilias,question pool,e-learning,conversion
|
|
10
|
+
Classifier: Intended Audience :: Education
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Requires-Python: >=3.12
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
20
|
+
Requires-Dist: pytest-cov>=4; extra == "dev"
|
|
21
|
+
Requires-Dist: ruff>=0.1; extra == "dev"
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# iliasqc
|
|
25
|
+
|
|
26
|
+
[](https://pypi.org/project/iliasqc/)
|
|
27
|
+
[](https://anaconda.org/conda-forge/iliasqc)
|
|
28
|
+
[](https://github.com/famosab/iliasqc/actions/workflows/tests.yml)
|
|
29
|
+
[](LICENSE)
|
|
30
|
+
[](https://github.com/famosab/iliasqc/security/dependabot)
|
|
31
|
+
|
|
32
|
+
Python package to convert structured text files into ILIAS-compatible question pool zip archives. Supports single/multiple choice and gap-fill question types, plus automated quiz combination generation.
|
|
33
|
+
|
|
34
|
+
This package is based on [Kaffeedrache/Tiqi](https://github.com/Kaffeedrache/Tiqi).
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
- **Multiple question types**: Single choice, multiple choice, and gap-fill questions
|
|
39
|
+
- **QTI 1.2 compliant**: Generates ILIAS-compatible XML format
|
|
40
|
+
- **Python API**: Use programmatically in your Python code
|
|
41
|
+
- **CLI tool**: Convert files from the command line
|
|
42
|
+
- **Template generator**: Create question file templates with examples
|
|
43
|
+
- **Quiz combinations**: Generate multiple pools and find optimal combinations to reach target point totals
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
### pip
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install iliasqc
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### conda / mamba (conda-forge)
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
conda install -c conda-forge iliasqc
|
|
57
|
+
# or
|
|
58
|
+
mamba install -c conda-forge iliasqc
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Question File Format
|
|
62
|
+
|
|
63
|
+
Questions are defined in `.txt` files with special syntax:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
# TITLE: My Question Pool
|
|
67
|
+
# DESCRIPTION: A collection of questions
|
|
68
|
+
|
|
69
|
+
[t][s] Single Choice Question @1
|
|
70
|
+
Question text goes here.
|
|
71
|
+
_ Correct answer
|
|
72
|
+
- Incorrect answer
|
|
73
|
+
- Another wrong answer
|
|
74
|
+
|
|
75
|
+
[t][m] Multiple Choice Question @2
|
|
76
|
+
Which options are correct?
|
|
77
|
+
- Wrong answer
|
|
78
|
+
_ Correct answer 1
|
|
79
|
+
_ Correct answer 2
|
|
80
|
+
- Wrong again
|
|
81
|
+
|
|
82
|
+
[t][g] Gap-Fill Question @1
|
|
83
|
+
The capital of France is [gap]Paris[/gap].
|
|
84
|
+
The capital of Germany is [gap]Berlin[/gap].
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Syntax Reference
|
|
88
|
+
|
|
89
|
+
| Marker | Description |
|
|
90
|
+
|--------|-------------|
|
|
91
|
+
| `[t]` | Question start marker (required) |
|
|
92
|
+
| `[s]` | Single choice question |
|
|
93
|
+
| `[m]` | Multiple choice question |
|
|
94
|
+
| `[g]` | Gap-fill question |
|
|
95
|
+
| `_` | Correct answer (for MC questions) |
|
|
96
|
+
| `-` | Incorrect answer (for MC questions) |
|
|
97
|
+
| `[gap]...[/gap]` | Gap to fill |
|
|
98
|
+
| `@N` | Points for the question (e.g., `@2`) |
|
|
99
|
+
| `# TITLE:` | Pool title metadata |
|
|
100
|
+
| `# DESCRIPTION:` | Pool description metadata |
|
|
101
|
+
|
|
102
|
+
## Usage
|
|
103
|
+
|
|
104
|
+
### Command Line
|
|
105
|
+
|
|
106
|
+
Convert a question file to ILIAS zip archive:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
iliasqc convert questions.txt
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Specify custom output path:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
iliasqc convert questions.txt -o my_pool.zip
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Override title and description:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
iliasqc convert questions.txt -t "My Pool" --description "My description"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Filter questions by point value:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
iliasqc convert questions.txt -p 2
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### Quiz Combinations
|
|
131
|
+
|
|
132
|
+
Generate multiple pools (one per point value) and find combinations to reach a target:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
iliasqc combine questions.txt -t 20
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
This will:
|
|
139
|
+
1. Create separate zip files for each point value found in your questions
|
|
140
|
+
2. Find all valid combinations that sum to 20 points
|
|
141
|
+
3. Display a table showing the combinations ranked by balance
|
|
142
|
+
4. Export a CSV file with the combinations
|
|
143
|
+
|
|
144
|
+
Options:
|
|
145
|
+
- `-t, --target`: Target total points (required)
|
|
146
|
+
- `-o, --output`: Output directory (default: same as input file)
|
|
147
|
+
- `-c, --combinations`: Maximum number of combinations to show (default: 10)
|
|
148
|
+
- `--csv-only`: Only output CSV, skip the table display
|
|
149
|
+
|
|
150
|
+
Example output:
|
|
151
|
+
```
|
|
152
|
+
Quiz Combinations for 20.0 Points
|
|
153
|
+
======================================================================
|
|
154
|
+
|
|
155
|
+
Available Pools:
|
|
156
|
+
- My Pool (5 points): 8 questions
|
|
157
|
+
- My Pool (4 points): 12 questions
|
|
158
|
+
- My Pool (2 points): 15 questions
|
|
159
|
+
|
|
160
|
+
──────────────────────────────────────────────────────────────────────
|
|
161
|
+
Rank Questions Balance Combination
|
|
162
|
+
──────────────────────────────────────────────────────────────────────
|
|
163
|
+
|
|
164
|
+
1 5 ●●●● 2x My Pool (5 points) + 5x My Pool (2 points)
|
|
165
|
+
2 4 ●●●○ 5x My Pool (4 points)
|
|
166
|
+
3 6 ●●●○ 3x My Pool (4 points) + 5x My Pool (2 points)
|
|
167
|
+
──────────────────────────────────────────────────────────────────────
|
|
168
|
+
|
|
169
|
+
Tip: Lower balance score = more diverse quiz
|
|
170
|
+
|
|
171
|
+
Generated 3 pools:
|
|
172
|
+
- My Pool_2pt_pool.zip: 15 questions
|
|
173
|
+
- My Pool_4pt_pool.zip: 12 questions
|
|
174
|
+
- My Pool_5pt_pool.zip: 8 questions
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Export as QTI XML (without creating zip archive):
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
iliasqc qti questions.txt -o output.xml
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Generate a question template file:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
iliasqc template -o my_template.txt
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Generate template without examples:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
iliasqc template -o basic_template.txt --no-examples
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Python API
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from iliasqc import txt_to_zip, txt_to_qti, generate_template
|
|
199
|
+
|
|
200
|
+
# Convert to ILIAS zip archive
|
|
201
|
+
output_path = txt_to_zip("questions.txt")
|
|
202
|
+
print(f"Created: {output_path}")
|
|
203
|
+
|
|
204
|
+
# Convert to QTI XML only
|
|
205
|
+
xml_path = txt_to_qti("questions.txt", "output.xml")
|
|
206
|
+
print(f"Created: {xml_path}")
|
|
207
|
+
|
|
208
|
+
# Generate a template
|
|
209
|
+
template_path = generate_template("my_template.txt")
|
|
210
|
+
print(f"Created template: {template_path}")
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### Quiz Combination API
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
from iliasqc import (
|
|
217
|
+
generate_quiz_combinations,
|
|
218
|
+
generate_pools_by_points,
|
|
219
|
+
find_combinations,
|
|
220
|
+
format_combinations_table,
|
|
221
|
+
export_combinations_csv,
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
# Generate pools and find combinations (full pipeline)
|
|
225
|
+
pools, combinations = generate_quiz_combinations(
|
|
226
|
+
"questions.txt",
|
|
227
|
+
target_points=20,
|
|
228
|
+
output_dir=".",
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
# Or use individual functions
|
|
232
|
+
pools = generate_pools_by_points("questions.txt")
|
|
233
|
+
combinations = find_combinations(pools, target_points=20)
|
|
234
|
+
|
|
235
|
+
# Format as a text table
|
|
236
|
+
table = format_combinations_table(combinations, pools, target_points=20)
|
|
237
|
+
print(table)
|
|
238
|
+
|
|
239
|
+
# Export to CSV
|
|
240
|
+
csv_path = export_combinations_csv(".", combinations, target_points=20)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Development
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
git clone https://github.com/famosab/iliasqc.git
|
|
247
|
+
cd iliasqc
|
|
248
|
+
pip install -e ".[dev]"
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Running Tests
|
|
252
|
+
|
|
253
|
+
Run all tests:
|
|
254
|
+
```bash
|
|
255
|
+
pytest tests/
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Run with coverage:
|
|
259
|
+
```bash
|
|
260
|
+
pytest tests/ --cov=iliasqc --cov-report=term-missing
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Code Quality
|
|
264
|
+
|
|
265
|
+
Run linting checks:
|
|
266
|
+
```bash
|
|
267
|
+
ruff check src/ tests/
|
|
268
|
+
ruff format --check src/ tests/
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Fix linting issues automatically:
|
|
272
|
+
```bash
|
|
273
|
+
ruff check --fix src/ tests/
|
|
274
|
+
ruff format src/ tests/
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Continuous Integration
|
|
278
|
+
|
|
279
|
+
The project uses GitHub Actions for automated testing. The CI pipeline runs on every push and pull request, testing against Python 3.12, 3.13, and 3.14.
|
|
280
|
+
|
|
281
|
+
## License
|
|
282
|
+
|
|
283
|
+
MIT – see [LICENSE](LICENSE).
|
iliasqc-0.1.0/README.md
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# iliasqc
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/iliasqc/)
|
|
4
|
+
[](https://anaconda.org/conda-forge/iliasqc)
|
|
5
|
+
[](https://github.com/famosab/iliasqc/actions/workflows/tests.yml)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://github.com/famosab/iliasqc/security/dependabot)
|
|
8
|
+
|
|
9
|
+
Python package to convert structured text files into ILIAS-compatible question pool zip archives. Supports single/multiple choice and gap-fill question types, plus automated quiz combination generation.
|
|
10
|
+
|
|
11
|
+
This package is based on [Kaffeedrache/Tiqi](https://github.com/Kaffeedrache/Tiqi).
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Multiple question types**: Single choice, multiple choice, and gap-fill questions
|
|
16
|
+
- **QTI 1.2 compliant**: Generates ILIAS-compatible XML format
|
|
17
|
+
- **Python API**: Use programmatically in your Python code
|
|
18
|
+
- **CLI tool**: Convert files from the command line
|
|
19
|
+
- **Template generator**: Create question file templates with examples
|
|
20
|
+
- **Quiz combinations**: Generate multiple pools and find optimal combinations to reach target point totals
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
### pip
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install iliasqc
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### conda / mamba (conda-forge)
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
conda install -c conda-forge iliasqc
|
|
34
|
+
# or
|
|
35
|
+
mamba install -c conda-forge iliasqc
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Question File Format
|
|
39
|
+
|
|
40
|
+
Questions are defined in `.txt` files with special syntax:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
# TITLE: My Question Pool
|
|
44
|
+
# DESCRIPTION: A collection of questions
|
|
45
|
+
|
|
46
|
+
[t][s] Single Choice Question @1
|
|
47
|
+
Question text goes here.
|
|
48
|
+
_ Correct answer
|
|
49
|
+
- Incorrect answer
|
|
50
|
+
- Another wrong answer
|
|
51
|
+
|
|
52
|
+
[t][m] Multiple Choice Question @2
|
|
53
|
+
Which options are correct?
|
|
54
|
+
- Wrong answer
|
|
55
|
+
_ Correct answer 1
|
|
56
|
+
_ Correct answer 2
|
|
57
|
+
- Wrong again
|
|
58
|
+
|
|
59
|
+
[t][g] Gap-Fill Question @1
|
|
60
|
+
The capital of France is [gap]Paris[/gap].
|
|
61
|
+
The capital of Germany is [gap]Berlin[/gap].
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Syntax Reference
|
|
65
|
+
|
|
66
|
+
| Marker | Description |
|
|
67
|
+
|--------|-------------|
|
|
68
|
+
| `[t]` | Question start marker (required) |
|
|
69
|
+
| `[s]` | Single choice question |
|
|
70
|
+
| `[m]` | Multiple choice question |
|
|
71
|
+
| `[g]` | Gap-fill question |
|
|
72
|
+
| `_` | Correct answer (for MC questions) |
|
|
73
|
+
| `-` | Incorrect answer (for MC questions) |
|
|
74
|
+
| `[gap]...[/gap]` | Gap to fill |
|
|
75
|
+
| `@N` | Points for the question (e.g., `@2`) |
|
|
76
|
+
| `# TITLE:` | Pool title metadata |
|
|
77
|
+
| `# DESCRIPTION:` | Pool description metadata |
|
|
78
|
+
|
|
79
|
+
## Usage
|
|
80
|
+
|
|
81
|
+
### Command Line
|
|
82
|
+
|
|
83
|
+
Convert a question file to ILIAS zip archive:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
iliasqc convert questions.txt
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Specify custom output path:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
iliasqc convert questions.txt -o my_pool.zip
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Override title and description:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
iliasqc convert questions.txt -t "My Pool" --description "My description"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Filter questions by point value:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
iliasqc convert questions.txt -p 2
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### Quiz Combinations
|
|
108
|
+
|
|
109
|
+
Generate multiple pools (one per point value) and find combinations to reach a target:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
iliasqc combine questions.txt -t 20
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
This will:
|
|
116
|
+
1. Create separate zip files for each point value found in your questions
|
|
117
|
+
2. Find all valid combinations that sum to 20 points
|
|
118
|
+
3. Display a table showing the combinations ranked by balance
|
|
119
|
+
4. Export a CSV file with the combinations
|
|
120
|
+
|
|
121
|
+
Options:
|
|
122
|
+
- `-t, --target`: Target total points (required)
|
|
123
|
+
- `-o, --output`: Output directory (default: same as input file)
|
|
124
|
+
- `-c, --combinations`: Maximum number of combinations to show (default: 10)
|
|
125
|
+
- `--csv-only`: Only output CSV, skip the table display
|
|
126
|
+
|
|
127
|
+
Example output:
|
|
128
|
+
```
|
|
129
|
+
Quiz Combinations for 20.0 Points
|
|
130
|
+
======================================================================
|
|
131
|
+
|
|
132
|
+
Available Pools:
|
|
133
|
+
- My Pool (5 points): 8 questions
|
|
134
|
+
- My Pool (4 points): 12 questions
|
|
135
|
+
- My Pool (2 points): 15 questions
|
|
136
|
+
|
|
137
|
+
──────────────────────────────────────────────────────────────────────
|
|
138
|
+
Rank Questions Balance Combination
|
|
139
|
+
──────────────────────────────────────────────────────────────────────
|
|
140
|
+
|
|
141
|
+
1 5 ●●●● 2x My Pool (5 points) + 5x My Pool (2 points)
|
|
142
|
+
2 4 ●●●○ 5x My Pool (4 points)
|
|
143
|
+
3 6 ●●●○ 3x My Pool (4 points) + 5x My Pool (2 points)
|
|
144
|
+
──────────────────────────────────────────────────────────────────────
|
|
145
|
+
|
|
146
|
+
Tip: Lower balance score = more diverse quiz
|
|
147
|
+
|
|
148
|
+
Generated 3 pools:
|
|
149
|
+
- My Pool_2pt_pool.zip: 15 questions
|
|
150
|
+
- My Pool_4pt_pool.zip: 12 questions
|
|
151
|
+
- My Pool_5pt_pool.zip: 8 questions
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Export as QTI XML (without creating zip archive):
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
iliasqc qti questions.txt -o output.xml
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Generate a question template file:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
iliasqc template -o my_template.txt
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Generate template without examples:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
iliasqc template -o basic_template.txt --no-examples
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Python API
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from iliasqc import txt_to_zip, txt_to_qti, generate_template
|
|
176
|
+
|
|
177
|
+
# Convert to ILIAS zip archive
|
|
178
|
+
output_path = txt_to_zip("questions.txt")
|
|
179
|
+
print(f"Created: {output_path}")
|
|
180
|
+
|
|
181
|
+
# Convert to QTI XML only
|
|
182
|
+
xml_path = txt_to_qti("questions.txt", "output.xml")
|
|
183
|
+
print(f"Created: {xml_path}")
|
|
184
|
+
|
|
185
|
+
# Generate a template
|
|
186
|
+
template_path = generate_template("my_template.txt")
|
|
187
|
+
print(f"Created template: {template_path}")
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### Quiz Combination API
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
from iliasqc import (
|
|
194
|
+
generate_quiz_combinations,
|
|
195
|
+
generate_pools_by_points,
|
|
196
|
+
find_combinations,
|
|
197
|
+
format_combinations_table,
|
|
198
|
+
export_combinations_csv,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
# Generate pools and find combinations (full pipeline)
|
|
202
|
+
pools, combinations = generate_quiz_combinations(
|
|
203
|
+
"questions.txt",
|
|
204
|
+
target_points=20,
|
|
205
|
+
output_dir=".",
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
# Or use individual functions
|
|
209
|
+
pools = generate_pools_by_points("questions.txt")
|
|
210
|
+
combinations = find_combinations(pools, target_points=20)
|
|
211
|
+
|
|
212
|
+
# Format as a text table
|
|
213
|
+
table = format_combinations_table(combinations, pools, target_points=20)
|
|
214
|
+
print(table)
|
|
215
|
+
|
|
216
|
+
# Export to CSV
|
|
217
|
+
csv_path = export_combinations_csv(".", combinations, target_points=20)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Development
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
git clone https://github.com/famosab/iliasqc.git
|
|
224
|
+
cd iliasqc
|
|
225
|
+
pip install -e ".[dev]"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Running Tests
|
|
229
|
+
|
|
230
|
+
Run all tests:
|
|
231
|
+
```bash
|
|
232
|
+
pytest tests/
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Run with coverage:
|
|
236
|
+
```bash
|
|
237
|
+
pytest tests/ --cov=iliasqc --cov-report=term-missing
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Code Quality
|
|
241
|
+
|
|
242
|
+
Run linting checks:
|
|
243
|
+
```bash
|
|
244
|
+
ruff check src/ tests/
|
|
245
|
+
ruff format --check src/ tests/
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Fix linting issues automatically:
|
|
249
|
+
```bash
|
|
250
|
+
ruff check --fix src/ tests/
|
|
251
|
+
ruff format src/ tests/
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Continuous Integration
|
|
255
|
+
|
|
256
|
+
The project uses GitHub Actions for automated testing. The CI pipeline runs on every push and pull request, testing against Python 3.12, 3.13, and 3.14.
|
|
257
|
+
|
|
258
|
+
## License
|
|
259
|
+
|
|
260
|
+
MIT – see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=64"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "iliasqc"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python package to convert txt files into zip folder that can be uploaded to Ilias to create question pools."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Famke Bäuerle" }
|
|
13
|
+
]
|
|
14
|
+
keywords = ["ilias", "question pool", "e-learning", "conversion"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Intended Audience :: Education",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"Programming Language :: Python :: 3.14",
|
|
21
|
+
]
|
|
22
|
+
requires-python = ">=3.12"
|
|
23
|
+
dependencies = []
|
|
24
|
+
|
|
25
|
+
[project.optional-dependencies]
|
|
26
|
+
dev = [
|
|
27
|
+
"pytest>=7",
|
|
28
|
+
"pytest-cov>=4",
|
|
29
|
+
"ruff>=0.1",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/famosab/iliasqc"
|
|
34
|
+
"Bug Tracker" = "https://github.com/famosab/iliasqc/issues"
|
|
35
|
+
|
|
36
|
+
[project.scripts]
|
|
37
|
+
iliasqc = "iliasqc.cli:main"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools.packages.find]
|
|
40
|
+
where = ["src"]
|
|
41
|
+
|
|
42
|
+
[tool.pytest.ini_options]
|
|
43
|
+
testpaths = ["tests"]
|
|
44
|
+
python_files = ["test_*.py"]
|
|
45
|
+
python_classes = ["Test*"]
|
|
46
|
+
python_functions = ["test_*"]
|
|
47
|
+
|
|
48
|
+
[tool.coverage.run]
|
|
49
|
+
source = ["src/iliasqc"]
|
|
50
|
+
branch = true
|
|
51
|
+
|
|
52
|
+
[tool.coverage.report]
|
|
53
|
+
exclude_lines = [
|
|
54
|
+
"pragma: no cover",
|
|
55
|
+
"def __repr__",
|
|
56
|
+
"raise AssertionError",
|
|
57
|
+
"raise NotImplementedError",
|
|
58
|
+
"if __name__ == .__main__.:",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[tool.ruff]
|
|
62
|
+
line-length = 100
|
|
63
|
+
target-version = "py312"
|
|
64
|
+
|
|
65
|
+
[tool.ruff.lint]
|
|
66
|
+
select = [
|
|
67
|
+
"E", # pycodestyle errors
|
|
68
|
+
"W", # pycodestyle warnings
|
|
69
|
+
"F", # pyflakes
|
|
70
|
+
"I", # isort
|
|
71
|
+
"B", # flake8-bugbear
|
|
72
|
+
"C4", # flake8-comprehensions
|
|
73
|
+
"UP", # pyupgrade
|
|
74
|
+
]
|
|
75
|
+
ignore = [
|
|
76
|
+
"E501", # line too long (handled by formatter)
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
[tool.ruff.lint.isort]
|
|
80
|
+
known-first-party = ["iliasqc"]
|
iliasqc-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""iliasqc – convert txt files into ILIAS-compatible question-pool zip archives."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
4
|
+
|
|
5
|
+
from iliasqc.combine import (
|
|
6
|
+
PoolCombination,
|
|
7
|
+
PoolInfo,
|
|
8
|
+
export_combinations_csv,
|
|
9
|
+
find_combinations,
|
|
10
|
+
format_combinations_table,
|
|
11
|
+
generate_pools_by_points,
|
|
12
|
+
generate_quiz_combinations,
|
|
13
|
+
)
|
|
14
|
+
from iliasqc.convert import txt_to_qti, txt_to_zip
|
|
15
|
+
from iliasqc.ilias import (
|
|
16
|
+
create_ilias_archive,
|
|
17
|
+
export_target_point_combinations_csv,
|
|
18
|
+
update_pool_overview_csv,
|
|
19
|
+
)
|
|
20
|
+
from iliasqc.parser import (
|
|
21
|
+
Answer,
|
|
22
|
+
Question,
|
|
23
|
+
extract_metadata,
|
|
24
|
+
extract_point_values,
|
|
25
|
+
parse_question_file,
|
|
26
|
+
)
|
|
27
|
+
from iliasqc.qti import convert_to_qti, create_question
|
|
28
|
+
from iliasqc.template import generate_template
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
__version__ = version("iliasqc")
|
|
32
|
+
except PackageNotFoundError:
|
|
33
|
+
__version__ = "unknown"
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
"__version__",
|
|
37
|
+
"Answer",
|
|
38
|
+
"Question",
|
|
39
|
+
"PoolCombination",
|
|
40
|
+
"PoolInfo",
|
|
41
|
+
"convert_to_qti",
|
|
42
|
+
"create_question",
|
|
43
|
+
"create_ilias_archive",
|
|
44
|
+
"export_combinations_csv",
|
|
45
|
+
"export_target_point_combinations_csv",
|
|
46
|
+
"extract_metadata",
|
|
47
|
+
"extract_point_values",
|
|
48
|
+
"find_combinations",
|
|
49
|
+
"format_combinations_table",
|
|
50
|
+
"generate_pools_by_points",
|
|
51
|
+
"generate_quiz_combinations",
|
|
52
|
+
"generate_template",
|
|
53
|
+
"parse_question_file",
|
|
54
|
+
"txt_to_qti",
|
|
55
|
+
"txt_to_zip",
|
|
56
|
+
"update_pool_overview_csv",
|
|
57
|
+
]
|