excel2moodle 0.3.6__py3-none-any.whl → 0.4.0__py3-none-any.whl

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.
@@ -1,2 +1,5 @@
1
1
  [console_scripts]
2
2
  excel2moodle = excel2moodle.__main__:main
3
+
4
+ [gui_scripts]
5
+ excel2moodle = excel2moodle.__main__:main
@@ -1,267 +0,0 @@
1
- """This Module holds the related Functions for writing the Questions to an xml-File.
2
-
3
- It is planned to rework those Functions, because they're not quite elegant.
4
- """
5
-
6
-
7
- def write_question_MC(
8
- save_dir,
9
- ID,
10
- name,
11
- s_1,
12
- s_2,
13
- s_3,
14
- points_avail,
15
- ans_type,
16
- true_ans,
17
- false_ans,
18
- pic,
19
- ) -> None:
20
- """Funktion schreibt MC-Frage auf Grundlage der übergebenen strings nach Pfad f_path."""
21
- perc = [
22
- "100",
23
- "50",
24
- "33.33333",
25
- "25",
26
- "20",
27
- "16.66667",
28
- "14.28571",
29
- "12.5",
30
- "11.11111",
31
- "10",
32
- ]
33
- num_true = len(true_ans)
34
- perc_true = perc[num_true - 1]
35
- num_false = len(false_ans)
36
- perc_false = "-" + perc_true
37
- q_name = ID + "_" + name
38
- f_path = (save_dir / q_name).with_suffix(".xml")
39
-
40
- with open(f_path, "w", encoding="utf-8") as f:
41
- # Text schreiben
42
- f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
43
- f.write("<quiz>\n")
44
- f.write('<question type="multichoice">\n')
45
- f.write("<name>\n")
46
- f.write("<text>" + q_name + "</text>\n")
47
- f.write("</name>\n")
48
- f.write('<questiontext format="html">\n')
49
- if pic != 0:
50
- f.write(
51
- '<text><![CDATA[<p dir="ltr" style="text-align: left;"> <b>ID '
52
- + str(ID)
53
- + "</b> <br></p>"
54
- '<p dir="ltr" style="text-align: left;">' + s_1 + "<br></p>"
55
- '<p dir="ltr" style="text-align: left;">' + s_2 + "<br></p>"
56
- '<p dir="ltr" style="text-align: left;">' + s_3 + "<br><br></p>"
57
- '<br><img src="@@PLUGINFILE@@/'
58
- + str(ID)
59
- + '.svg" alt="Bild" width="500"><br>'
60
- "<br></p>]]></text>\n",
61
- )
62
- f.write(str(pic))
63
- else:
64
- f.write(
65
- '<text><![CDATA[<p dir="ltr" style="text-align: left;"> <b>ID '
66
- + q_name
67
- + " </b> <br></p>"
68
- '<p dir="ltr" style="text-align: left;">' + s_1 + "<br></p>"
69
- '<p dir="ltr" style="text-align: left;">' + s_2 + "<br></p>"
70
- '<p dir="ltr" style="text-align: left;">' + s_3 + "<br></p>"
71
- "<br></p>]]></text>\n",
72
- )
73
-
74
- f.write("</questiontext>\n")
75
- f.write('<generalfeedback format="html">\n')
76
- f.write("<text></text>\n")
77
- f.write("</generalfeedback>\n")
78
- f.write("<defaultgrade>" + str(float(points_avail)) + "</defaultgrade>\n")
79
- f.write("<penalty>0.3333333</penalty>\n")
80
- f.write("<hidden>0</hidden>\n")
81
- f.write("<idnumber>" + ID + "</idnumber>\n")
82
- f.write("<single>false</single>\n")
83
- f.write("<shuffleanswers>true</shuffleanswers>\n")
84
- f.write("<answernumbering>abc</answernumbering>\n")
85
- f.write("<showstandardinstruction>0</showstandardinstruction>\n")
86
- f.write('<correctfeedback format="html">\n')
87
- f.write("<text>Die Frage wurde richtig beantwortet.</text>\n")
88
- f.write("</correctfeedback>\n")
89
- f.write('<partiallycorrectfeedback format="html">\n')
90
- f.write("<text>Die Frage wurde teilweise richtig beantwortet.</text>\n")
91
- f.write("</partiallycorrectfeedback>\n")
92
- f.write('<incorrectfeedback format="html">\n')
93
- f.write("<text>Die Frage wurde falsch beantwortet.</text>\n")
94
- f.write("</incorrectfeedback>\n")
95
- f.write("<shownumcorrect/>\n")
96
-
97
- # Alle richtigen Antworten
98
- for i in range(num_true):
99
- if ans_type == "unit":
100
- f.write('<answer fraction="' + perc_true + '" format="html">\n')
101
- f.write(
102
- '<text><![CDATA[<p dir="ltr" style="text-align: left;">\\(\\mathrm{'
103
- + true_ans[i]
104
- + "}\\)<br></p>]]></text>\n",
105
- )
106
- f.write('<feedback format="html">\n')
107
- f.write(
108
- '<text><![CDATA[<p dir="ltr" style="text-align: left;"><span class="" style="color: rgb(152, 202, 62);">richtig</span><br></p>]]></text>\n',
109
- )
110
- f.write("</feedback>\n")
111
- f.write("</answer>\n")
112
-
113
- elif ans_type == "math":
114
- f.write('<answer fraction="' + perc_true + '" format="html">\n')
115
- f.write(
116
- '<text><![CDATA[<p dir="ltr" style="text-align: left;">\\('
117
- + true_ans[i]
118
- + "\\)<br></p>]]></text>\n",
119
- )
120
- f.write('<feedback format="html">\n')
121
- f.write(
122
- '<text><![CDATA[<p dir="ltr" style="text-align: left;"><span class="" style="color: rgb(152, 202, 62);">richtig</span><br></p>]]></text>\n',
123
- )
124
- f.write("</feedback>\n")
125
- f.write("</answer>\n")
126
-
127
- elif ans_type == "text":
128
- f.write('<answer fraction="' + perc_true + '" format="html">\n')
129
- f.write(
130
- '<text><![CDATA[<p dir="ltr" style="text-align: left;">'
131
- + true_ans[i]
132
- + "<br></p>]]></text>\n",
133
- )
134
- f.write('<feedback format="html">\n')
135
- f.write(
136
- '<text><![CDATA[<p dir="ltr" style="text-align: left;"><span class="" style="color: rgb(152, 202, 62);">richtig</span><br></p>]]></text>\n',
137
- )
138
- f.write("</feedback>\n")
139
- f.write("</answer>\n")
140
-
141
- # Alle falschen Antworten
142
- for i in range(num_false):
143
- if ans_type == "unit":
144
- f.write('<answer fraction="' + perc_false + '" format="html">\n')
145
- f.write(
146
- '<text><![CDATA[<p dir="ltr" style="text-align: left;">\\(\\mathrm{'
147
- + false_ans[i]
148
- + "}\\)<br></p>]]></text>\n",
149
- )
150
- f.write('<feedback format="html">\n')
151
- f.write(
152
- '<text><![CDATA[<p dir="ltr" style="text-align: left;"><span class="" style="color: rgb(239, 69, 64);">falsch</span><br></p>]]></text>\n',
153
- )
154
- f.write("</feedback>\n")
155
- f.write("</answer>\n")
156
-
157
- elif ans_type == "math":
158
- f.write('<answer fraction="' + perc_false + '" format="html">\n')
159
- f.write(
160
- '<text><![CDATA[<p dir="ltr" style="text-align: left;">\\('
161
- + false_ans[i]
162
- + "\\)<br></p>]]></text>\n",
163
- )
164
- f.write('<feedback format="html">\n')
165
- f.write(
166
- '<text><![CDATA[<p dir="ltr" style="text-align: left;"><span class="" style="color: rgb(239, 69, 64);">falsch</span><br></p>]]></text>\n',
167
- )
168
- f.write("</feedback>\n")
169
- f.write("</answer>\n")
170
-
171
- elif ans_type == "text":
172
- f.write('<answer fraction="' + perc_false + '" format="html">\n')
173
- f.write(
174
- '<text><![CDATA[<p dir="ltr" style="text-align: left;">'
175
- + false_ans[i]
176
- + "<br></p>]]></text>\n",
177
- )
178
- f.write('<feedback format="html">\n')
179
- f.write(
180
- '<text><![CDATA[<p dir="ltr" style="text-align: left;"><span class="" style="color: rgb(239, 69, 64);">falsch</span><br></p>]]></text>\n',
181
- )
182
- f.write("</feedback>\n")
183
- f.write("</answer>\n")
184
-
185
- f.write("</question>\n")
186
- f.write("</quiz>\n")
187
-
188
-
189
- def write_question_NF(
190
- save_dir,
191
- ID,
192
- name,
193
- s_1,
194
- s_2,
195
- s_3,
196
- b_str,
197
- points_avail,
198
- result,
199
- pic,
200
- tol_abs,
201
- picID=None,
202
- ) -> None:
203
- """Funktion schreibt NF-Frage auf Grundlage der übergebenen strings nach Pfad f_path."""
204
- if picID is None:
205
- picID = ID
206
- q_name = ID + "_" + name
207
- f_path = (save_dir / q_name).with_suffix(".xml")
208
-
209
- with open(f_path, "w", encoding="utf-8") as f:
210
- # Text schreiben
211
- f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
212
- f.write("<quiz>\n")
213
- f.write('<question type="numerical">\n')
214
- f.write("<name>\n")
215
- f.write("<text>" + q_name + "</text>\n")
216
- f.write("</name>\n")
217
- f.write('<questiontext format="html">\n')
218
- if pic != 0:
219
- f.write(
220
- '<text><![CDATA[<p dir="ltr" style="text-align: left;"> <b>ID '
221
- + str(ID)
222
- + " </b> <br></p>"
223
- '<p dir="ltr" style="text-align: left;">' + s_1 + "<br></p>"
224
- '<p dir="ltr" style="text-align: left;">' + s_2 + "<br></p>"
225
- '<p dir="ltr" style="text-align: left;">' + s_3 + b_str + "<br><br></p>"
226
- '<br><img src="@@PLUGINFILE@@/'
227
- + str(picID)
228
- + '.svg" alt="Bild" width="500"><br>'
229
- "<br></p>]]></text>\n",
230
- )
231
- f.write(pic)
232
- else:
233
- f.write(
234
- '<text><![CDATA[<p dir="ltr" style="text-align: left;"> <b>ID '
235
- + ID
236
- + " </b> <br></p>"
237
- '<p dir="ltr" style="text-align: left;">' + s_1 + "<br></p>"
238
- '<p dir="ltr" style="text-align: left;">' + s_2 + "<br></p>"
239
- '<p dir="ltr" style="text-align: left;">'
240
- + s_3
241
- + b_str
242
- + "]]></text>\n",
243
- )
244
-
245
- f.write("</questiontext>\n")
246
- f.write('<generalfeedback format="html">\n')
247
- f.write("<text></text>\n")
248
- f.write("</generalfeedback>\n")
249
- f.write("<defaultgrade>" + str(float(points_avail)) + "</defaultgrade>\n")
250
- f.write("<penalty>0.3333333</penalty>\n")
251
- f.write("<hidden>0</hidden>\n")
252
- f.write("<idnumber>" + ID + "</idnumber>\n")
253
- f.write('<answer fraction="100" format="moodle_auto_format">\n')
254
- f.write("<text>" + str(result) + "</text>\n")
255
- f.write('<feedback format="html">\n')
256
- f.write(
257
- '<text><![CDATA[<p dir="ltr" style="text-align: left;"><span class="" style="color: rgb(152, 202, 62);">Das Ergebnis ist im Rahmen der 1%-Toleranz korrekt.</span><br></p>]]></text>\n',
258
- )
259
- f.write("</feedback>\n")
260
- f.write("<tolerance>" + str(tol_abs) + "</tolerance>\n")
261
- f.write("</answer>\n")
262
- f.write("<unitgradingtype>0</unitgradingtype>\n")
263
- f.write("<unitpenalty>0.1000000</unitpenalty>\n")
264
- f.write("<showunits>3</showunits>\n")
265
- f.write("<unitsleft>0</unitsleft>\n")
266
- f.write("</question>\n")
267
- f.write("</quiz>\n")
@@ -1,123 +0,0 @@
1
- """Settings module provides the adjusted subclass of ``PySide6.QtCore.QSettings``."""
2
-
3
- import logging
4
- from enum import StrEnum
5
- from pathlib import Path
6
- from typing import Literal, overload
7
-
8
- from PySide6.QtCore import QSettings, QTimer, Signal
9
-
10
- logger = logging.getLogger(__name__)
11
-
12
-
13
- class SettingsKey(StrEnum):
14
- def __new__(
15
- cls,
16
- key: str,
17
- typ: type,
18
- default: str | float | Path | bool | None,
19
- ):
20
- """Define new settings class."""
21
- obj = str.__new__(cls, key)
22
- obj._value_ = key
23
- obj._default_ = default
24
- obj._typ_ = typ
25
- return obj
26
-
27
- @property
28
- def default(self) -> str | int | float | Path | bool | None:
29
- """Get default value for the key."""
30
- return self._default_
31
-
32
- def typ(self) -> type:
33
- """Get default value for the key."""
34
- return self._typ_
35
-
36
- QUESTIONVARIANT = "testgen/defaultQuestionVariant", int, 0
37
- INCLUDEINCATS = "testgen/includeCats", bool, False
38
- PARSERNF_TOLERANCE = "parser/nf/tolerance", int, 1
39
- PICTURESUBFOLDER = "core/pictureSubFolder", str, "Abbildungen"
40
- PICTUREFOLDER = "core/pictureFolder", Path, None
41
- SPREADSHEETFOLDER = "core/spreadsheetFolder", Path, None
42
- LOGLEVEL = "core/loglevel", str, "INFO"
43
- LOGFILE = "core/logfile", str, "excel2moodleLogFile.log"
44
-
45
-
46
- class Settings(QSettings):
47
- """Settings for Excel2moodle."""
48
-
49
- shPathChanged = Signal(Path)
50
-
51
- def __init__(self) -> None:
52
- """Instantiate the settings."""
53
- super().__init__("jbosse3", "excel2moodle")
54
- logger.info("Settings are stored under: %s", self.fileName())
55
- if self.contains(SettingsKey.SPREADSHEETFOLDER):
56
- self.sheet = self.get(SettingsKey.SPREADSHEETFOLDER)
57
- if self.sheet.is_file():
58
- QTimer.singleShot(300, self._emitSpreadsheetChanged)
59
-
60
- def _emitSpreadsheetChanged(self) -> None:
61
- self.shPathChanged.emit(self.sheet)
62
-
63
- @overload
64
- def get(
65
- self,
66
- value: Literal[SettingsKey.QUESTIONVARIANT, SettingsKey.PARSERNF_TOLERANCE],
67
- ) -> int: ...
68
- @overload
69
- def get(self, value: Literal[SettingsKey.INCLUDEINCATS]) -> bool: ...
70
- @overload
71
- def get(
72
- self,
73
- value: Literal[
74
- SettingsKey.PICTURESUBFOLDER, SettingsKey.LOGLEVEL, SettingsKey.LOGFILE
75
- ],
76
- ) -> str: ...
77
- @overload
78
- def get(
79
- self,
80
- value: Literal[SettingsKey.PICTUREFOLDER, SettingsKey.SPREADSHEETFOLDER],
81
- ) -> Path: ...
82
-
83
- def get(self, value: SettingsKey):
84
- """Get the typesafe settings value."""
85
- logger.debug("entering get method. searched typ: %s", value.typ())
86
- if value.typ() is Path:
87
- logger.debug("trying to acess a path object from settings")
88
- path = self.value(value, defaultValue=value.default)
89
- try:
90
- path.resolve(strict=True)
91
- except ValueError:
92
- logger.warning(
93
- f"The settingsvalue {value} couldn't be fetched with correct typ",
94
- )
95
- return value.default
96
- return path
97
- raw = self.value(value, defaultValue=value.default, type=value.typ())
98
- logger.debug("read a settings Value: %s of type: %s", value, value.typ())
99
- try:
100
- return value.typ()(raw)
101
- except (ValueError, TypeError):
102
- logger.warning(
103
- f"The settingsvalue {value} couldn't be fetched with correct typ",
104
- )
105
- return value.default
106
-
107
- def set(self, settingKey: SettingsKey, value: float | bool | Path | str) -> None:
108
- """Set the setting to value."""
109
- # if isinstance(value, SettingsKey.type):
110
- self.setValue(settingKey, value)
111
- logger.info("Saved the Setting %s = %s", settingKey, value)
112
- # else:
113
- # logger.error("trying to save setting with wrong type not possible")
114
-
115
- def setSpreadsheet(self, sheet: Path) -> None:
116
- """Save spreadsheet path and emit the changed event."""
117
- if isinstance(sheet, Path):
118
- self.sheet = sheet.resolve(strict=True)
119
- logpath = str(self.sheet.parent / "excel2moodleLogFile.log")
120
- self.set(SettingsKey.LOGFILE, logpath)
121
- self.set(SettingsKey.SPREADSHEETFOLDER, self.sheet)
122
- self.shPathChanged.emit(sheet)
123
- return
@@ -1,33 +0,0 @@
1
- excel2moodle/__init__.py,sha256=tJopLP1Oks1wtiFPiW25qKwgJWa-X_C0UNQijM-pRnw,2236
2
- excel2moodle/__main__.py,sha256=gPhAh5GmRw-atxu-3JCdElFBKFw5ZB-G_G3xoPPJQVM,812
3
- excel2moodle/logger.py,sha256=WomQ_EAiqZ2oVHNReG4KdfGRMrJl3jC3LIr8cbvOlbY,3084
4
- excel2moodle/core/__init__.py,sha256=H4Bt6u076RKb6BH5F58nHLQvYPDUoayosM_Onyr9yT0,398
5
- excel2moodle/core/category.py,sha256=VunNsfRUv7O8L3XMe1BB2EFxtfCAJFaRafRYRKF15kE,3006
6
- excel2moodle/core/dataStructure.py,sha256=G-XpkcmP4ZpySvpi9ykvETrP-U69BNtjTR762ZekuBk,6217
7
- excel2moodle/core/etHelpers.py,sha256=i8DAx7YBxrQqzbXFsU-pIvYMPHSRhYci-JvuzY1MzeI,2299
8
- excel2moodle/core/exceptions.py,sha256=VgbxrnoR9RRnmDYK2rbB_Bv00r7NLWET6FgddPwo3uw,748
9
- excel2moodle/core/globals.py,sha256=OGBxkgD19etaMP6sTtsTZ_u8NXbnHYdCQYAu9E3pcgE,3692
10
- excel2moodle/core/numericMultiQ.py,sha256=vr-gYogu2sf2a_Bhvhnu1ZSZFZXM32MfhJesjTkoOQM,2618
11
- excel2moodle/core/parser.py,sha256=jsBMjluc5OICCkrtT4WNVwO26-MaBOTuiOUbQhN2d6g,15232
12
- excel2moodle/core/question.py,sha256=ZubBhS3n7wRFgtcKZ4AoUBSsxLyIM1wsmzsBqbSab-I,6489
13
- excel2moodle/core/questionValidator.py,sha256=a12bPd6hdE5vuj8aoXA0qXVZ0pI98X-uUBzF0oIbzYk,4810
14
- excel2moodle/core/questionWriter.py,sha256=UiWbrtNSiQiYY_x3sF3nz6Ic0b_lL0uWHyeDNDtFvPM,10985
15
- excel2moodle/core/stringHelpers.py,sha256=XZAyXKZcQT_bAQSb9tBQs5tMC5soJf_ZhYFHrDX9ck4,2994
16
- excel2moodle/extra/__init__.py,sha256=PM-id60HD21A3IcGC_fCYFihS8osBGZMIJCcN-ZRsIM,293
17
- excel2moodle/extra/equationVerification.py,sha256=GLJl1r90d8AAiNy0H2hooZrg3D6aEwNfifYKAe3aGxM,3921
18
- excel2moodle/ui/__init__.py,sha256=4EdGtpzwH3rgw4xW9E5x9kdPQYwKbo9rehHRZTNxCrQ,44
19
- excel2moodle/ui/appUi.py,sha256=wbvAPrPFAZaXP7sPQmGt9P4KoKgzhAAwnxdh6gN1Gak,10355
20
- excel2moodle/ui/dialogs.py,sha256=EgAKcydF4clyEweocjmtyCdsQJdQmvY-LVzOlu_cl_8,5320
21
- excel2moodle/ui/questionPreviewDialog.py,sha256=_rJvz1GM90aNnj3P6SugEezK7JW6m74ZALgkChohWLM,4980
22
- excel2moodle/ui/settings.py,sha256=eN5h1YeSYJ84-hDe13ief31Am5y46CxahoRx5Cn8usQ,4360
23
- excel2moodle/ui/treewidget.py,sha256=mTRqmZHMZT3QTTvt5Gw9L-yl4KdhhulkF7O1KBwW-_E,2449
24
- excel2moodle/ui/variantDialog.py,sha256=snVaF3_YAc7NWjMRg7NzbjL_PzNbOpt4eiqElkE46io,5414
25
- excel2moodle/ui/windowDoc.py,sha256=IciZpwrLnGzIQV1aCdKQBg6km3oufHGs8havTFzNJyU,1055
26
- excel2moodle/ui/windowEquationChecker.py,sha256=fLyal3sbJwpthWCAxLB5vbSFOX23JoivoYksNp3mZVY,7925
27
- excel2moodle/ui/windowMain.py,sha256=FsaApCyWgngnWPb46R8_01z8q4XeWxRFVqewSIt742c,19027
28
- excel2moodle-0.3.6.dist-info/licenses/LICENSE,sha256=ywQqe6Sitymkf2lV2NRcx_aGsaC-KbSl_EfEsRXmNRw,35135
29
- excel2moodle-0.3.6.dist-info/METADATA,sha256=O1NBWfHhc6EMKGMaBJRHW9DmPWotmbJKUzN16gv3wsA,2945
30
- excel2moodle-0.3.6.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
31
- excel2moodle-0.3.6.dist-info/entry_points.txt,sha256=myfMLDThuGgWHMJDPPfILiZqo_7D3fhmDdJGqWOAjPw,60
32
- excel2moodle-0.3.6.dist-info/top_level.txt,sha256=5V1xRUQ9o7UmOCmNoWCZPAuy5nXp3Qbzyqch8fUGT_c,13
33
- excel2moodle-0.3.6.dist-info/RECORD,,