excel2moodle 0.3.2__py3-none-any.whl → 0.3.4__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.
- excel2moodle/__init__.py +72 -49
- excel2moodle/__main__.py +5 -15
- excel2moodle/core/category.py +53 -62
- excel2moodle/core/dataStructure.py +87 -52
- excel2moodle/core/etHelpers.py +21 -16
- excel2moodle/core/exceptions.py +11 -4
- excel2moodle/core/globals.py +41 -28
- excel2moodle/core/numericMultiQ.py +18 -13
- excel2moodle/core/parser.py +202 -149
- excel2moodle/core/question.py +120 -51
- excel2moodle/core/questionValidator.py +48 -37
- excel2moodle/core/stringHelpers.py +41 -23
- excel2moodle/extra/__init__.py +1 -3
- excel2moodle/extra/equationVerification.py +40 -22
- excel2moodle/ui/appUi.py +113 -69
- excel2moodle/ui/dialogs.py +36 -19
- excel2moodle/ui/settings.py +48 -10
- {excel2moodle-0.3.2.dist-info → excel2moodle-0.3.4.dist-info}/METADATA +7 -6
- excel2moodle-0.3.4.dist-info/RECORD +32 -0
- {excel2moodle-0.3.2.dist-info → excel2moodle-0.3.4.dist-info}/WHEEL +1 -1
- excel2moodle-0.3.4.dist-info/entry_points.txt +2 -0
- excel2moodle-0.3.2.dist-info/RECORD +0 -31
- {excel2moodle-0.3.2.dist-info → excel2moodle-0.3.4.dist-info}/licenses/LICENSE +0 -0
- {excel2moodle-0.3.2.dist-info → excel2moodle-0.3.4.dist-info}/top_level.txt +0 -0
excel2moodle/core/exceptions.py
CHANGED
@@ -1,20 +1,27 @@
|
|
1
|
-
|
2
1
|
from excel2moodle.core.globals import DFIndex
|
3
2
|
|
4
3
|
|
5
4
|
class QNotParsedException(Exception):
|
6
|
-
def __init__(self, message:str, qID:str|int, *args, **kwargs)->None:
|
5
|
+
def __init__(self, message: str, qID: str | int, *args, **kwargs) -> None:
|
7
6
|
super().__init__(message, *args, **kwargs)
|
8
7
|
self.qID = qID
|
9
8
|
|
9
|
+
|
10
10
|
class NanException(QNotParsedException):
|
11
11
|
def __init__(self, message, qID, field, *args, **kwargs):
|
12
12
|
super().__init__(message, qID, *args, **kwargs)
|
13
13
|
self.field = field
|
14
14
|
|
15
|
+
|
15
16
|
class InvalidFieldException(Exception):
|
16
|
-
def __init__(
|
17
|
+
def __init__(
|
18
|
+
self,
|
19
|
+
message: str,
|
20
|
+
qID: str,
|
21
|
+
field: DFIndex | list[DFIndex],
|
22
|
+
*args: object,
|
23
|
+
**kwargs,
|
24
|
+
) -> None:
|
17
25
|
super().__init__(message, *args, **kwargs)
|
18
26
|
self.field = field
|
19
27
|
self.index = qID
|
20
|
-
|
excel2moodle/core/globals.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
from enum import Enum, StrEnum
|
2
|
+
|
2
3
|
import lxml.etree as ET
|
3
4
|
|
4
5
|
questionTypes = {
|
@@ -7,14 +8,15 @@ questionTypes = {
|
|
7
8
|
"MC": "multichoice",
|
8
9
|
}
|
9
10
|
|
11
|
+
|
10
12
|
class DFIndex(StrEnum):
|
11
13
|
"""This Enum holds the identifier string for for the spreadsheet and the string for the xml-tag
|
12
|
-
|
14
|
+
|
13
15
|
Each enum corresponds to a list of two values.
|
14
16
|
The first Value is the index in the spreadsheet, the second is the name of the xml-tag
|
15
17
|
"""
|
16
18
|
|
17
|
-
TEXT
|
19
|
+
TEXT = "text"
|
18
20
|
BPOINTS = "bulletPoints"
|
19
21
|
TRUE = "true"
|
20
22
|
FALSE = "false"
|
@@ -25,50 +27,61 @@ class DFIndex(StrEnum):
|
|
25
27
|
NUMBER = "number"
|
26
28
|
ANSTYPE = "answerType"
|
27
29
|
|
30
|
+
|
28
31
|
class TextElements(Enum):
|
29
|
-
PLEFT ="p","text-align: left;"
|
32
|
+
PLEFT = "p", "text-align: left;"
|
30
33
|
SPANRED = "span", "color: rgb(239, 69, 64)"
|
31
34
|
SPANGREEN = "span", "color: rgb(152, 202, 62)"
|
32
|
-
SPANORANGE = "span","color: rgb(152, 100, 100)"
|
33
|
-
ULIST =
|
34
|
-
|
35
|
+
SPANORANGE = "span", "color: rgb(152, 100, 100)"
|
36
|
+
ULIST = (
|
37
|
+
"ul",
|
38
|
+
"",
|
39
|
+
)
|
40
|
+
LISTITEM = (
|
41
|
+
"li",
|
42
|
+
"text-align: left;",
|
43
|
+
)
|
35
44
|
|
36
|
-
def create(self, tag:str|None=None):
|
45
|
+
def create(self, tag: str | None = None):
|
37
46
|
if tag is None:
|
38
47
|
tag, style = self.value
|
39
|
-
else:
|
48
|
+
else:
|
49
|
+
style = self.value[1]
|
40
50
|
return ET.Element(tag, dir="ltr", style=style)
|
41
51
|
|
42
52
|
@property
|
43
|
-
def style(
|
53
|
+
def style(
|
54
|
+
self,
|
55
|
+
) -> str:
|
44
56
|
return self.value[1]
|
45
57
|
|
58
|
+
|
46
59
|
class XMLTags(StrEnum):
|
47
|
-
def __new__(cls, value:str, dfkey: DFIndex|None = None):
|
60
|
+
def __new__(cls, value: str, dfkey: DFIndex | None = None):
|
48
61
|
obj = str.__new__(cls, value)
|
49
62
|
obj._value_ = value
|
50
63
|
if dfkey is not None:
|
51
64
|
obj._dfkey_ = dfkey
|
52
65
|
return obj
|
53
66
|
|
54
|
-
def __init__(self,_:str, dfkey:DFIndex|None =None, getEle=None
|
67
|
+
def __init__(self, _: str, dfkey: DFIndex | None = None, getEle=None) -> None:
|
55
68
|
if isinstance(dfkey, DFIndex):
|
56
|
-
self._dfkey_:str=dfkey
|
69
|
+
self._dfkey_: str = dfkey
|
57
70
|
if getEle:
|
58
|
-
self._getEle_:object=getEle
|
71
|
+
self._getEle_: object = getEle
|
59
72
|
|
60
73
|
@property
|
61
|
-
def dfkey(self)->str:
|
74
|
+
def dfkey(self) -> str:
|
62
75
|
return self._dfkey_
|
63
76
|
|
64
|
-
def set(self,getEle)->None:
|
77
|
+
def set(self, getEle) -> None:
|
65
78
|
self._getEle_ = getEle
|
66
79
|
|
67
80
|
def __repr__(self) -> str:
|
68
81
|
msg = []
|
69
|
-
msg.append(f"XML Tag {self.value
|
82
|
+
msg.append(f"XML Tag {self.value=}")
|
70
83
|
if hasattr(self, "_dfkey_"):
|
71
|
-
msg.append(f"Df Key {self.dfkey
|
84
|
+
msg.append(f"Df Key {self.dfkey=}")
|
72
85
|
return "\n".join(msg)
|
73
86
|
|
74
87
|
NAME = "name", DFIndex.NAME
|
@@ -89,31 +102,32 @@ class XMLTags(StrEnum):
|
|
89
102
|
ANSWER = "answer"
|
90
103
|
TOLERANCE = "tolerance"
|
91
104
|
|
105
|
+
|
92
106
|
feedBElements = {
|
93
|
-
XMLTags.CORFEEDB:TextElements.SPANGREEN.create(),
|
107
|
+
XMLTags.CORFEEDB: TextElements.SPANGREEN.create(),
|
94
108
|
XMLTags.PCORFEEDB: TextElements.SPANORANGE.create(),
|
95
109
|
XMLTags.INCORFEEDB: TextElements.SPANRED.create(),
|
96
110
|
XMLTags.ANSFEEDBACK: TextElements.SPANGREEN.create(),
|
97
111
|
XMLTags.GENFEEDB: TextElements.SPANGREEN.create(),
|
98
112
|
}
|
99
113
|
feedbackStr = {
|
100
|
-
XMLTags.CORFEEDB:"Die Frage wurde richtig beantwortet",
|
114
|
+
XMLTags.CORFEEDB: "Die Frage wurde richtig beantwortet",
|
101
115
|
XMLTags.PCORFEEDB: "Die Frage wurde teilweise richtig beantwortet",
|
102
116
|
XMLTags.INCORFEEDB: "Die Frage wurde Falsch beantwortet",
|
103
117
|
XMLTags.GENFEEDB: "Sie haben eine Antwort abgegeben",
|
104
118
|
"right": "richtig",
|
105
119
|
"wrong": "falsch",
|
106
|
-
"right1Percent": "Gratultaion, die Frage wurde im Rahmen der Toleranz richtig beantwortet"
|
120
|
+
"right1Percent": "Gratultaion, die Frage wurde im Rahmen der Toleranz richtig beantwortet",
|
107
121
|
}
|
108
122
|
|
109
123
|
parserSettings = {
|
110
|
-
"Parser"
|
111
|
-
|
112
|
-
|
113
|
-
},
|
124
|
+
"Parser": {
|
125
|
+
"standards": {
|
126
|
+
"hidden": 0,
|
114
127
|
},
|
115
|
-
|
116
|
-
|
128
|
+
},
|
129
|
+
"MCParser": {
|
130
|
+
"standards": {
|
117
131
|
"single": "false",
|
118
132
|
"shuffleanswers": "true",
|
119
133
|
"answernumbering": "abc",
|
@@ -121,8 +135,7 @@ parserSettings = {
|
|
121
135
|
"shownumcorrect": "",
|
122
136
|
},
|
123
137
|
},
|
124
|
-
"NFParser"
|
138
|
+
"NFParser": {
|
125
139
|
"standards": {},
|
126
140
|
},
|
127
141
|
}
|
128
|
-
|
@@ -6,37 +6,40 @@ As well it returns a bullet points string that shows the numerical values corres
|
|
6
6
|
"""
|
7
7
|
|
8
8
|
import re as re
|
9
|
+
|
9
10
|
import pandas as pd
|
10
11
|
from asteval import Interpreter
|
11
12
|
|
12
13
|
astEval = Interpreter()
|
13
14
|
|
14
15
|
|
15
|
-
def getVariablesDict(df: pd.DataFrame, keyList: list, index:int)-> dict:
|
16
|
+
def getVariablesDict(df: pd.DataFrame, keyList: list, index: int) -> dict:
|
16
17
|
"""Liest alle Variablen-Listen deren Name in ``keyList`` ist aus dem DataFrame im Column[index]"""
|
17
18
|
dic = {}
|
18
19
|
for k in keyList:
|
19
20
|
val = df.loc[str(k)][index]
|
20
|
-
if
|
21
|
+
if isinstance(val, str) and val is not None:
|
21
22
|
li = val.split(";")
|
22
23
|
dic[str(k)] = li
|
23
|
-
else:
|
24
|
+
else:
|
24
25
|
dic[str(k)] = [str(val)]
|
25
26
|
print(f"Folgende Variablen wurden gefunden:\n{dic}\n")
|
26
27
|
return dic
|
27
28
|
|
28
|
-
|
29
|
+
|
30
|
+
def setParameters(parameters: dict, index: int) -> None:
|
29
31
|
"""Ubergibt die Parameter mit entsprechenden Variablen-Namen an den asteval-Interpreter.
|
30
32
|
|
31
33
|
Dann kann dieser die equation loesen.
|
32
34
|
"""
|
33
|
-
for k,v in parameters.items():
|
35
|
+
for k, v in parameters.items():
|
34
36
|
comma = re.compile(r",")
|
35
|
-
value = comma.sub(".",v[index])
|
37
|
+
value = comma.sub(".", v[index])
|
36
38
|
astEval.symtable[k] = float(value)
|
37
39
|
return None
|
38
40
|
|
39
|
-
|
41
|
+
|
42
|
+
def insertVariablesToBPoints(varDict: dict, bulletPoints: str, index: int) -> str:
|
40
43
|
"""
|
41
44
|
Für jeden Eintrag im varDict, wird im bulletPoints String der Substring "{key}" durch value[index] ersetzt
|
42
45
|
"""
|
@@ -46,23 +49,25 @@ def insertVariablesToBPoints(varDict: dict, bulletPoints: str, index: int)-> str
|
|
46
49
|
bulletPoints = matcher.sub(str(v[index]), bulletPoints)
|
47
50
|
return bulletPoints
|
48
51
|
|
49
|
-
|
52
|
+
|
53
|
+
def getVarsList(bps: str) -> list:
|
50
54
|
"""
|
51
55
|
Durchsucht den bulletPoints String nach den Variablen, die als "{var}" gekennzeichnet sind
|
52
56
|
"""
|
53
57
|
vars = re.findall(r"\{\w\}", str(bps))
|
54
|
-
variablen=[]
|
58
|
+
variablen = []
|
55
59
|
for v in vars:
|
56
60
|
variablen.append(v.strip("{}"))
|
57
61
|
return variablen
|
58
62
|
|
59
63
|
|
60
|
-
def parseNumericMultiQuestion(
|
61
|
-
|
62
|
-
|
64
|
+
def parseNumericMultiQuestion(
|
65
|
+
datFrame: pd.DataFrame, bulletPoints: str, equation: str, questionIndex: int
|
66
|
+
) -> tuple[list[str], list[float]]:
|
63
67
|
"""Berechnet die Ergebnisse anhand der Variablen in *bulletPoints*
|
64
68
|
|
65
|
-
Gibt eine Liste mit allen Ergebnissen zurück
|
69
|
+
Gibt eine Liste mit allen Ergebnissen zurück
|
70
|
+
und eine Liste mit den bulletPoints-Strings, die die Numerischen Variablen enthalten
|
66
71
|
"""
|
67
72
|
results = []
|
68
73
|
bps = []
|