excel2moodle 0.6.5__tar.gz → 0.7.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 (54) hide show
  1. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/PKG-INFO +16 -1
  2. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/README.md +15 -0
  3. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/question.py +8 -3
  4. excel2moodle-0.7.0/excel2moodle/extra/equationChecker.py +141 -0
  5. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/extra/variableGenerator.py +1 -2
  6. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/question_types/cloze.py +1 -1
  7. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/ui/UI_equationChecker.py +105 -115
  8. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/ui/UI_variableGenerator.py +1 -1
  9. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/ui/appUi.py +45 -43
  10. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle.egg-info/PKG-INFO +16 -1
  11. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle.egg-info/SOURCES.txt +1 -2
  12. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/pyproject.toml +1 -1
  13. excel2moodle-0.6.5/excel2moodle/extra/equationVerification.py +0 -126
  14. excel2moodle-0.6.5/excel2moodle/ui/equationChecker.py +0 -70
  15. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/LICENSE +0 -0
  16. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/__init__.py +0 -0
  17. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/__main__.py +0 -0
  18. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/__init__.py +0 -0
  19. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/bullets.py +0 -0
  20. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/category.py +0 -0
  21. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/dataStructure.py +0 -0
  22. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/etHelpers.py +0 -0
  23. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/exceptions.py +0 -0
  24. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/globals.py +0 -0
  25. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/parser.py +0 -0
  26. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/settings.py +0 -0
  27. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/stringHelpers.py +0 -0
  28. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/core/validator.py +0 -0
  29. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/extra/__init__.py +0 -0
  30. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/extra/scriptCaller.py +0 -0
  31. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/extra/updateQuery.py +0 -0
  32. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/logger.py +0 -0
  33. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/question_types/__init__.py +0 -0
  34. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/question_types/mc.py +0 -0
  35. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/question_types/nf.py +0 -0
  36. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/question_types/nfm.py +0 -0
  37. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/ui/UI_exportSettingsDialog.py +0 -0
  38. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/ui/UI_mainWindow.py +0 -0
  39. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/ui/UI_updateDlg.py +0 -0
  40. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/ui/UI_variantDialog.py +0 -0
  41. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/ui/__init__.py +0 -0
  42. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/ui/dialogs.py +0 -0
  43. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle/ui/treewidget.py +0 -0
  44. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle.egg-info/dependency_links.txt +0 -0
  45. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle.egg-info/entry_points.txt +0 -0
  46. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle.egg-info/requires.txt +0 -0
  47. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/excel2moodle.egg-info/top_level.txt +0 -0
  48. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/setup.cfg +0 -0
  49. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/test/test_bullets.py +0 -0
  50. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/test/test_feedbacking.py +0 -0
  51. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/test/test_nfmParsing.py +0 -0
  52. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/test/test_parseQuestion.py +0 -0
  53. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/test/test_picture.py +0 -0
  54. {excel2moodle-0.6.5 → excel2moodle-0.7.0}/test/test_questionDataGet.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: excel2moodle
3
- Version: 0.6.5
3
+ Version: 0.7.0
4
4
  Summary: A package for converting questions from a spreadsheet, to valid moodle-xml
5
5
  Author: Jakob Bosse
6
6
  License-Expression: GPL-3.0-or-later
@@ -90,6 +90,21 @@ If You want to support my work as well, you can by me a [coffee](https://ko-fi.c
90
90
 
91
91
  # Changelogs
92
92
 
93
+ ## 0.7.0 (2025-09-30)
94
+ Rework of the equation checker done!
95
+
96
+ ### feature (1 change)
97
+
98
+ - [finalized equation Checker](https://gitlab.com/jbosse3/excel2moodle/-/commit/55e3891d3da56357ad00f672a86c2690d551d21c)
99
+
100
+ ### documentation (1 change)
101
+
102
+ - [Documented feedback usages](https://gitlab.com/jbosse3/excel2moodle/-/commit/6f50ce023a3235b3f34b6272a4ce5057346f8751)
103
+
104
+ ### improvement (1 change)
105
+
106
+ - [MainWindow got a currentQuestion property](https://gitlab.com/jbosse3/excel2moodle/-/commit/59b18e158201357b767a36dab0f300f88cb5e9ad)
107
+
93
108
  ## 0.6.5 (2025-09-02)
94
109
  Added Scripted Media Support now with the module
95
110
 
@@ -68,6 +68,21 @@ If You want to support my work as well, you can by me a [coffee](https://ko-fi.c
68
68
 
69
69
  # Changelogs
70
70
 
71
+ ## 0.7.0 (2025-09-30)
72
+ Rework of the equation checker done!
73
+
74
+ ### feature (1 change)
75
+
76
+ - [finalized equation Checker](https://gitlab.com/jbosse3/excel2moodle/-/commit/55e3891d3da56357ad00f672a86c2690d551d21c)
77
+
78
+ ### documentation (1 change)
79
+
80
+ - [Documented feedback usages](https://gitlab.com/jbosse3/excel2moodle/-/commit/6f50ce023a3235b3f34b6272a4ce5057346f8751)
81
+
82
+ ### improvement (1 change)
83
+
84
+ - [MainWindow got a currentQuestion property](https://gitlab.com/jbosse3/excel2moodle/-/commit/59b18e158201357b767a36dab0f300f88cb5e9ad)
85
+
71
86
  ## 0.6.5 (2025-09-02)
72
87
  Added Scripted Media Support now with the module
73
88
 
@@ -250,7 +250,7 @@ class Parametrics:
250
250
  self.equations: dict[int, str] = (
251
251
  equation if isinstance(equation, dict) else {1: equation}
252
252
  )
253
- self._resultChecker: dict[int, float] = (
253
+ self.resultChecker: dict[int, float] = (
254
254
  firstResult if isinstance(firstResult, dict) else {1: firstResult}
255
255
  )
256
256
  self.id = identifier
@@ -258,6 +258,11 @@ class Parametrics:
258
258
  self.results: dict[int, list[float]] = {}
259
259
  self.logger = LogAdapterQuestionID(loggerObj, {"qID": self.id})
260
260
 
261
+ def setEquation(self, number: int, equation: str) -> None:
262
+ """Set the new equation and update all the calculations."""
263
+ self.equations[number] = equation
264
+ self._calculateResults()
265
+
261
266
  @property
262
267
  def variants(self) -> int:
263
268
  number = 1000
@@ -315,12 +320,12 @@ class Parametrics:
315
320
  result,
316
321
  )
317
322
  if variant == 0 and not math.isclose(
318
- result, self._resultChecker[num], rel_tol=0.01
323
+ result, self.resultChecker[num], rel_tol=0.01
319
324
  ):
320
325
  self.logger.warning(
321
326
  "The calculated result %s differs from given firstResult: %s",
322
327
  result,
323
- self._resultChecker,
328
+ self.resultChecker,
324
329
  )
325
330
  self.logger.debug(
326
331
  "Calculated result %s for variant %s", result, variant
@@ -0,0 +1,141 @@
1
+ """Verify the equations written into the ``result`` field of ParametricQuestion.
2
+
3
+ This module
4
+
5
+ #. It calculates all the answers obtained from the series of variables.
6
+ #. It compares the calculation of the first answer to the ``firstResult`` field.
7
+
8
+ Usage
9
+ =====
10
+
11
+ From the main UI
12
+ ----------------
13
+
14
+ #. Start this tool from the top bar in the main Window under the *Tools* section
15
+ #. A new window will open with the currently selected question
16
+ #. For Cloze Questions select the correct equation on the top
17
+ #. You can edit the equation in the middle field
18
+ #. Click on ``Check the equation now!`` and inspect the results.
19
+ #. If the first calculated result matches the value in the field ``firstResult`` your equation is probably right.
20
+ #. Now click on ``Save equation`` to copy all modified equations to the clipboard.
21
+ """
22
+
23
+ import logging
24
+ import math
25
+ from pathlib import Path
26
+
27
+ from PySide6.QtCore import Slot
28
+ from PySide6.QtWidgets import QApplication, QDialog, QMainWindow, QMessageBox
29
+
30
+ from excel2moodle import mainLogger
31
+ from excel2moodle.core.question import ParametricQuestion, Parametrics
32
+ from excel2moodle.extra.variableGenerator import populateDataSetTable
33
+ from excel2moodle.logger import LogWindowHandler
34
+ from excel2moodle.ui.UI_equationChecker import Ui_EquationChecker
35
+
36
+ logger = logging.getLogger(__name__)
37
+
38
+ loggerSignal = LogWindowHandler()
39
+ mainLogger.addHandler(loggerSignal)
40
+
41
+
42
+ class EqCheckerWindow(QDialog):
43
+ def __init__(self, parent: QMainWindow) -> None:
44
+ super().__init__(parent=parent)
45
+ self.mainWindow = parent
46
+ self.excelFile = Path()
47
+ self.ui = Ui_EquationChecker()
48
+ self.ui.setupUi(self)
49
+ self.ui.btnRunCheck.clicked.connect(
50
+ lambda: self.updateCalculation(),
51
+ )
52
+ self.ui.answerPartNum.valueChanged.connect(lambda: self.updateEquation())
53
+ self.ui.btnCancel.clicked.connect(self.reject)
54
+ self.ui.btnFetchQst.clicked.connect(lambda: self.updateQuestion())
55
+ self.ui.btnSave.clicked.connect(lambda: self.copyEquation())
56
+ self.parametrics: Parametrics
57
+
58
+ @Slot()
59
+ def updateQuestion(self) -> None:
60
+ """Get the current Question from the list and set up the checker."""
61
+ question = self.mainWindow.currentQuestion
62
+ if not isinstance(question, ParametricQuestion):
63
+ mainLogger.error("Can't check a question without parametrics")
64
+ return
65
+ self.ui.labelQuestionNum.setText(f"Question: {question.id}")
66
+ self.parametrics = question.parametrics
67
+ self.ui.answerPartNum.setValue(1)
68
+ self.ui.answerPartNum.setMaximum(len(self.parametrics.equations))
69
+ self.updateEquation()
70
+
71
+ @Slot()
72
+ def updateEquation(self) -> None:
73
+ """Update only the equation number of the same question."""
74
+ self.ui.equationText.clear()
75
+ eqVariant = self.ui.answerPartNum.value()
76
+ self.ui.lineFirstResult.setText(
77
+ str(self.parametrics.resultChecker.get(eqVariant))
78
+ )
79
+ if len(self.parametrics.equations) == 1:
80
+ self.ui.answerPartNum.hide()
81
+ self.ui.labelPartNum.hide()
82
+ else:
83
+ self.ui.answerPartNum.show()
84
+ self.ui.labelPartNum.show()
85
+ self.ui.equationText.appendPlainText(
86
+ str(self.parametrics.equations.get(eqVariant))
87
+ )
88
+ self.updateCalculation()
89
+
90
+ def updateCalculation(self) -> None:
91
+ """Calculate the current equation written in the textedit."""
92
+ equation = self.ui.equationText.toPlainText()
93
+ eqNum = self.ui.answerPartNum.value()
94
+ self.parametrics.setEquation(number=eqNum, equation=equation)
95
+ calculatedResult = self.parametrics.getResult(number=1, equation=eqNum)
96
+ check: bool = False
97
+ check = bool(
98
+ math.isclose(
99
+ calculatedResult,
100
+ self.parametrics.resultChecker.get(eqNum, 0),
101
+ rel_tol=0.01,
102
+ )
103
+ )
104
+ self.ui.lineCalculatedRes.setText(f"{calculatedResult}")
105
+ if check:
106
+ self.ui.lineCheckResult.setStyleSheet("color: rgb(24,150,0)")
107
+ self.ui.lineCheckResult.setText(
108
+ "[OK] Value of 'first result' matches calculated set 1"
109
+ )
110
+ logger.info(
111
+ "[OK] The first calculated result matches 'firstResult'",
112
+ )
113
+ else:
114
+ self.ui.lineCheckResult.setStyleSheet("color: rgb(255,0,0)")
115
+ self.ui.lineCheckResult.setText(
116
+ "[ERROR] Value of 'first result' doesn't match set 1"
117
+ )
118
+ logger.warning(
119
+ "The first calculated result does not match 'firstResult'",
120
+ )
121
+
122
+ populateDataSetTable(self.ui.tableVariables, self.parametrics)
123
+
124
+ @Slot()
125
+ def copyEquation(self) -> None:
126
+ clipb = QApplication.clipboard()
127
+ equationlist: list[str] = []
128
+ if len(self.parametrics.equations) > 1:
129
+ for i, eq in self.parametrics.equations.items():
130
+ equationlist.append(f"result:{i} \t{eq}")
131
+ else:
132
+ equationlist.append(f"result\t{self.parametrics.equations.get(1)}")
133
+ clipb.setText("\n".join(equationlist))
134
+ mainLogger.info("Copied equations to the clipboard")
135
+ QMessageBox.information(
136
+ self.mainWindow,
137
+ "Equation Copied!",
138
+ """All equations from the current parametric question are saved to the clipboard.\n
139
+ You can paste them with 'crtl + v' into the spreadsheet.
140
+ Make sure to import them with 'Tab' as the seperator.""",
141
+ )
@@ -26,7 +26,7 @@ class VariableGeneratorDialog(QDialog):
26
26
  self.ui.setupUi(self)
27
27
  self.origParametrics = parametrics
28
28
  self._generatedParametrics: Parametrics = Parametrics(
29
- parametrics.equations, parametrics._resultChecker, identifier="genr"
29
+ parametrics.equations, parametrics.resultChecker, identifier="genr"
30
30
  )
31
31
  # Load existing rules
32
32
  for rule in self.origParametrics.variableRules:
@@ -271,4 +271,3 @@ def populateDataSetTable(
271
271
  QTableWidgetItem(str(res)),
272
272
  )
273
273
  tableWidget.resizeColumnsToContents()
274
-
@@ -299,7 +299,7 @@ class ClozeQuestionParser(NFMQuestionParser):
299
299
  else:
300
300
  loclogger.info("Adding new equation to parametrics")
301
301
  self.question.parametrics.equations[num] = eq
302
- self.question.parametrics._resultChecker[num] = firstResult.get(
302
+ self.question.parametrics.resultChecker[num] = firstResult.get(
303
303
  num, 0.0
304
304
  )
305
305
  if not hasattr(part, "result"):
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'UI_equationChecker.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.1
6
+ ## Created by: Qt User Interface Compiler version 6.9.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -15,9 +15,10 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
15
15
  QFont, QFontDatabase, QGradient, QIcon,
16
16
  QImage, QKeySequence, QLinearGradient, QPainter,
17
17
  QPalette, QPixmap, QRadialGradient, QTransform)
18
- from PySide6.QtWidgets import (QApplication, QFrame, QGridLayout, QLabel,
19
- QLineEdit, QPlainTextEdit, QPushButton, QSizePolicy,
20
- QSpacerItem, QSpinBox, QTextEdit, QVBoxLayout,
18
+ from PySide6.QtWidgets import (QAbstractScrollArea, QApplication, QFrame, QGridLayout,
19
+ QHBoxLayout, QHeaderView, QLabel, QLineEdit,
20
+ QPlainTextEdit, QPushButton, QSizePolicy, QSpacerItem,
21
+ QSpinBox, QTableWidget, QTableWidgetItem, QVBoxLayout,
21
22
  QWidget)
22
23
 
23
24
  class Ui_EquationChecker(object):
@@ -25,7 +26,7 @@ class Ui_EquationChecker(object):
25
26
  if not EquationChecker.objectName():
26
27
  EquationChecker.setObjectName(u"EquationChecker")
27
28
  EquationChecker.setWindowModality(Qt.WindowModality.WindowModal)
28
- EquationChecker.resize(1213, 898)
29
+ EquationChecker.resize(650, 722)
29
30
  icon = QIcon(QIcon.fromTheme(QIcon.ThemeIcon.ListRemove))
30
31
  EquationChecker.setWindowIcon(icon)
31
32
  EquationChecker.setAutoFillBackground(False)
@@ -33,29 +34,21 @@ class Ui_EquationChecker(object):
33
34
  self.verticalLayout.setObjectName(u"verticalLayout")
34
35
  self.gridLayout = QGridLayout()
35
36
  self.gridLayout.setObjectName(u"gridLayout")
36
- self.label_2 = QLabel(EquationChecker)
37
- self.label_2.setObjectName(u"label_2")
38
- self.label_2.setMinimumSize(QSize(200, 0))
39
- self.label_2.setAlignment(Qt.AlignmentFlag.AlignCenter)
37
+ self.label_4 = QLabel(EquationChecker)
38
+ self.label_4.setObjectName(u"label_4")
40
39
 
41
- self.gridLayout.addWidget(self.label_2, 3, 0, 1, 1)
40
+ self.gridLayout.addWidget(self.label_4, 3, 2, 1, 1)
42
41
 
43
- self.equationText = QPlainTextEdit(EquationChecker)
44
- self.equationText.setObjectName(u"equationText")
45
- sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
46
- sizePolicy.setHorizontalStretch(0)
47
- sizePolicy.setVerticalStretch(0)
48
- sizePolicy.setHeightForWidth(self.equationText.sizePolicy().hasHeightForWidth())
49
- self.equationText.setSizePolicy(sizePolicy)
50
- self.equationText.setMinimumSize(QSize(0, 20))
51
- self.equationText.setBaseSize(QSize(0, 20))
42
+ self.answerPartNum = QSpinBox(EquationChecker)
43
+ self.answerPartNum.setObjectName(u"answerPartNum")
44
+ self.answerPartNum.setMinimum(1)
52
45
 
53
- self.gridLayout.addWidget(self.equationText, 3, 1, 1, 1)
46
+ self.gridLayout.addWidget(self.answerPartNum, 1, 3, 1, 1)
54
47
 
55
- self.label_4 = QLabel(EquationChecker)
56
- self.label_4.setObjectName(u"label_4")
48
+ self.labelPartNum = QLabel(EquationChecker)
49
+ self.labelPartNum.setObjectName(u"labelPartNum")
57
50
 
58
- self.gridLayout.addWidget(self.label_4, 4, 3, 1, 1)
51
+ self.gridLayout.addWidget(self.labelPartNum, 1, 2, 1, 1)
59
52
 
60
53
  self.lineCalculatedRes = QLineEdit(EquationChecker)
61
54
  self.lineCalculatedRes.setObjectName(u"lineCalculatedRes")
@@ -66,119 +59,114 @@ class Ui_EquationChecker(object):
66
59
  self.lineCalculatedRes.setReadOnly(True)
67
60
  self.lineCalculatedRes.setClearButtonEnabled(False)
68
61
 
69
- self.gridLayout.addWidget(self.lineCalculatedRes, 4, 4, 1, 1)
70
-
71
- self.lineCheckResult = QLineEdit(EquationChecker)
72
- self.lineCheckResult.setObjectName(u"lineCheckResult")
73
- font1 = QFont()
74
- font1.setBold(True)
75
- font1.setItalic(True)
76
- self.lineCheckResult.setFont(font1)
77
- self.lineCheckResult.setLayoutDirection(Qt.LayoutDirection.LeftToRight)
78
- self.lineCheckResult.setAlignment(Qt.AlignmentFlag.AlignCenter)
79
- self.lineCheckResult.setReadOnly(True)
80
-
81
- self.gridLayout.addWidget(self.lineCheckResult, 5, 4, 1, 1)
82
-
83
- self.buttonRunCheck = QPushButton(EquationChecker)
84
- self.buttonRunCheck.setObjectName(u"buttonRunCheck")
85
- font2 = QFont()
86
- font2.setPointSize(12)
87
- font2.setBold(True)
88
- self.buttonRunCheck.setFont(font2)
62
+ self.gridLayout.addWidget(self.lineCalculatedRes, 3, 3, 1, 1)
89
63
 
90
- self.gridLayout.addWidget(self.buttonRunCheck, 5, 1, 1, 1)
91
-
92
- self.label_8 = QLabel(EquationChecker)
93
- self.label_8.setObjectName(u"label_8")
94
- font3 = QFont()
95
- font3.setPointSize(12)
96
- self.label_8.setFont(font3)
64
+ self.lineFirstResult = QLineEdit(EquationChecker)
65
+ self.lineFirstResult.setObjectName(u"lineFirstResult")
66
+ self.lineFirstResult.setEnabled(True)
67
+ self.lineFirstResult.setFont(font)
68
+ self.lineFirstResult.setAlignment(Qt.AlignmentFlag.AlignCenter)
69
+ self.lineFirstResult.setReadOnly(True)
97
70
 
98
- self.gridLayout.addWidget(self.label_8, 5, 3, 1, 1)
71
+ self.gridLayout.addWidget(self.lineFirstResult, 2, 3, 1, 1)
99
72
 
100
- self.variableText = QTextEdit(EquationChecker)
101
- self.variableText.setObjectName(u"variableText")
73
+ self.label_3 = QLabel(EquationChecker)
74
+ self.label_3.setObjectName(u"label_3")
102
75
 
103
- self.gridLayout.addWidget(self.variableText, 3, 3, 1, 1)
76
+ self.gridLayout.addWidget(self.label_3, 2, 2, 1, 1)
104
77
 
105
- self.label_9 = QLabel(EquationChecker)
106
- self.label_9.setObjectName(u"label_9")
107
- self.label_9.setAlignment(Qt.AlignmentFlag.AlignCenter)
78
+ self.btnFetchQst = QPushButton(EquationChecker)
79
+ self.btnFetchQst.setObjectName(u"btnFetchQst")
108
80
 
109
- self.gridLayout.addWidget(self.label_9, 3, 2, 1, 1)
81
+ self.gridLayout.addWidget(self.btnFetchQst, 0, 3, 1, 1)
110
82
 
111
- self.label_10 = QLabel(EquationChecker)
112
- self.label_10.setObjectName(u"label_10")
83
+ self.labelQuestionNum = QLabel(EquationChecker)
84
+ self.labelQuestionNum.setObjectName(u"labelQuestionNum")
85
+ self.labelQuestionNum.setFont(font)
113
86
 
114
- self.gridLayout.addWidget(self.label_10, 2, 0, 1, 1)
87
+ self.gridLayout.addWidget(self.labelQuestionNum, 0, 2, 1, 1)
115
88
 
116
- self.answerPart = QSpinBox(EquationChecker)
117
- self.answerPart.setObjectName(u"answerPart")
118
89
 
119
- self.gridLayout.addWidget(self.answerPart, 2, 1, 1, 1)
90
+ self.verticalLayout.addLayout(self.gridLayout)
120
91
 
121
- self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
92
+ self.label_2 = QLabel(EquationChecker)
93
+ self.label_2.setObjectName(u"label_2")
122
94
 
123
- self.gridLayout.addItem(self.horizontalSpacer, 2, 2, 1, 1)
95
+ self.verticalLayout.addWidget(self.label_2)
124
96
 
125
- self.label_3 = QLabel(EquationChecker)
126
- self.label_3.setObjectName(u"label_3")
97
+ self.equationText = QPlainTextEdit(EquationChecker)
98
+ self.equationText.setObjectName(u"equationText")
99
+ sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
100
+ sizePolicy.setHorizontalStretch(0)
101
+ sizePolicy.setVerticalStretch(0)
102
+ sizePolicy.setHeightForWidth(self.equationText.sizePolicy().hasHeightForWidth())
103
+ self.equationText.setSizePolicy(sizePolicy)
104
+ self.equationText.setMinimumSize(QSize(0, 20))
105
+ self.equationText.setBaseSize(QSize(0, 20))
127
106
 
128
- self.gridLayout.addWidget(self.label_3, 2, 3, 1, 1)
107
+ self.verticalLayout.addWidget(self.equationText)
129
108
 
130
- self.lineFirstResult = QLineEdit(EquationChecker)
131
- self.lineFirstResult.setObjectName(u"lineFirstResult")
132
- self.lineFirstResult.setEnabled(True)
133
- self.lineFirstResult.setFont(font)
134
- self.lineFirstResult.setAlignment(Qt.AlignmentFlag.AlignCenter)
135
- self.lineFirstResult.setReadOnly(True)
109
+ self.horizontalLayout = QHBoxLayout()
110
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
111
+ self.horizontalLayout.setContentsMargins(-1, 5, -1, -1)
112
+ self.btnRunCheck = QPushButton(EquationChecker)
113
+ self.btnRunCheck.setObjectName(u"btnRunCheck")
114
+ font1 = QFont()
115
+ font1.setPointSize(12)
116
+ font1.setBold(True)
117
+ self.btnRunCheck.setFont(font1)
136
118
 
137
- self.gridLayout.addWidget(self.lineFirstResult, 2, 4, 1, 1)
119
+ self.horizontalLayout.addWidget(self.btnRunCheck)
138
120
 
139
- self.label_6 = QLabel(EquationChecker)
140
- self.label_6.setObjectName(u"label_6")
141
- font4 = QFont()
142
- font4.setPointSize(15)
143
- self.label_6.setFont(font4)
121
+ self.lineCheckResult = QLineEdit(EquationChecker)
122
+ self.lineCheckResult.setObjectName(u"lineCheckResult")
123
+ font2 = QFont()
124
+ font2.setBold(True)
125
+ font2.setItalic(True)
126
+ self.lineCheckResult.setFont(font2)
127
+ self.lineCheckResult.setLayoutDirection(Qt.LayoutDirection.LeftToRight)
128
+ self.lineCheckResult.setAlignment(Qt.AlignmentFlag.AlignCenter)
129
+ self.lineCheckResult.setReadOnly(True)
144
130
 
145
- self.gridLayout.addWidget(self.label_6, 1, 3, 1, 1)
131
+ self.horizontalLayout.addWidget(self.lineCheckResult)
146
132
 
147
- self.label_5 = QLabel(EquationChecker)
148
- self.label_5.setObjectName(u"label_5")
149
- self.label_5.setFont(font4)
150
133
 
151
- self.gridLayout.addWidget(self.label_5, 1, 1, 1, 1)
134
+ self.verticalLayout.addLayout(self.horizontalLayout)
152
135
 
136
+ self.line = QFrame(EquationChecker)
137
+ self.line.setObjectName(u"line")
138
+ self.line.setFrameShape(QFrame.Shape.HLine)
139
+ self.line.setFrameShadow(QFrame.Shadow.Sunken)
153
140
 
154
- self.verticalLayout.addLayout(self.gridLayout)
141
+ self.verticalLayout.addWidget(self.line)
155
142
 
156
- self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
143
+ self.tableVariables = QTableWidget(EquationChecker)
144
+ self.tableVariables.setObjectName(u"tableVariables")
145
+ sizePolicy.setHeightForWidth(self.tableVariables.sizePolicy().hasHeightForWidth())
146
+ self.tableVariables.setSizePolicy(sizePolicy)
147
+ self.tableVariables.setSizeAdjustPolicy(QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents)
157
148
 
158
- self.verticalLayout.addItem(self.verticalSpacer)
149
+ self.verticalLayout.addWidget(self.tableVariables)
159
150
 
160
- self.label_7 = QLabel(EquationChecker)
161
- self.label_7.setObjectName(u"label_7")
162
- self.label_7.setFont(font3)
151
+ self.horizontalLayout_2 = QHBoxLayout()
152
+ self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
153
+ self.horizontalLayout_2.setContentsMargins(-1, 5, -1, -1)
154
+ self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
163
155
 
164
- self.verticalLayout.addWidget(self.label_7)
156
+ self.horizontalLayout_2.addItem(self.horizontalSpacer)
165
157
 
166
- self.line = QFrame(EquationChecker)
167
- self.line.setObjectName(u"line")
168
- self.line.setFrameShape(QFrame.Shape.HLine)
169
- self.line.setFrameShadow(QFrame.Shadow.Sunken)
158
+ self.btnSave = QPushButton(EquationChecker)
159
+ self.btnSave.setObjectName(u"btnSave")
170
160
 
171
- self.verticalLayout.addWidget(self.line)
161
+ self.horizontalLayout_2.addWidget(self.btnSave)
172
162
 
173
- self.verticalLayout_2 = QVBoxLayout()
174
- self.verticalLayout_2.setObjectName(u"verticalLayout_2")
175
- self.textResultsOutput = QTextEdit(EquationChecker)
176
- self.textResultsOutput.setObjectName(u"textResultsOutput")
163
+ self.btnCancel = QPushButton(EquationChecker)
164
+ self.btnCancel.setObjectName(u"btnCancel")
177
165
 
178
- self.verticalLayout_2.addWidget(self.textResultsOutput)
166
+ self.horizontalLayout_2.addWidget(self.btnCancel)
179
167
 
180
168
 
181
- self.verticalLayout.addLayout(self.verticalLayout_2)
169
+ self.verticalLayout.addLayout(self.horizontalLayout_2)
182
170
 
183
171
 
184
172
  self.retranslateUi(EquationChecker)
@@ -188,20 +176,22 @@ class Ui_EquationChecker(object):
188
176
 
189
177
  def retranslateUi(self, EquationChecker):
190
178
  EquationChecker.setWindowTitle(QCoreApplication.translate("EquationChecker", u"Equation Checker", None))
191
- self.label_2.setText(QCoreApplication.translate("EquationChecker", u"Equation:", None))
192
179
  self.label_4.setText(QCoreApplication.translate("EquationChecker", u"calculated first Result", None))
180
+ self.labelPartNum.setText(QCoreApplication.translate("EquationChecker", u"Answer Part (Cloze)", None))
193
181
  self.lineCalculatedRes.setText(QCoreApplication.translate("EquationChecker", u"0.00", None))
194
- self.lineCheckResult.setText("")
195
- self.lineCheckResult.setPlaceholderText(QCoreApplication.translate("EquationChecker", u"waiting for check", None))
196
- self.buttonRunCheck.setText(QCoreApplication.translate("EquationChecker", u"Run Check now", None))
197
- self.label_8.setText(QCoreApplication.translate("EquationChecker", u"Check", None))
198
- self.label_9.setText(QCoreApplication.translate("EquationChecker", u"Variables:", None))
199
- self.label_10.setText(QCoreApplication.translate("EquationChecker", u"Answer Part (Cloze)", None))
200
- self.label_3.setText(QCoreApplication.translate("EquationChecker", u"firstResult from spreadsheet", None))
201
182
  self.lineFirstResult.setText(QCoreApplication.translate("EquationChecker", u"0.00", None))
202
183
  self.lineFirstResult.setPlaceholderText(QCoreApplication.translate("EquationChecker", u"waiting", None))
203
- self.label_6.setText(QCoreApplication.translate("EquationChecker", u"Output", None))
204
- self.label_5.setText(QCoreApplication.translate("EquationChecker", u"Input", None))
205
- self.label_7.setText(QCoreApplication.translate("EquationChecker", u"Calculated Values with corresponding properties", None))
184
+ self.label_3.setText(QCoreApplication.translate("EquationChecker", u"firstResult from spreadsheet", None))
185
+ #if QT_CONFIG(tooltip)
186
+ self.btnFetchQst.setToolTip(QCoreApplication.translate("EquationChecker", u"Get the last selected question from the main windows list.", None))
187
+ #endif // QT_CONFIG(tooltip)
188
+ self.btnFetchQst.setText(QCoreApplication.translate("EquationChecker", u"Fetch current question", None))
189
+ self.labelQuestionNum.setText(QCoreApplication.translate("EquationChecker", u"Question: ", None))
190
+ self.label_2.setText(QCoreApplication.translate("EquationChecker", u"Edit the equation below", None))
191
+ self.btnRunCheck.setText(QCoreApplication.translate("EquationChecker", u"Check the equation now !", None))
192
+ self.lineCheckResult.setText("")
193
+ self.lineCheckResult.setPlaceholderText(QCoreApplication.translate("EquationChecker", u"waiting for check", None))
194
+ self.btnSave.setText(QCoreApplication.translate("EquationChecker", u"Save equation", None))
195
+ self.btnCancel.setText(QCoreApplication.translate("EquationChecker", u"Close", None))
206
196
  # retranslateUi
207
197
 
@@ -3,7 +3,7 @@
3
3
  ################################################################################
4
4
  ## Form generated from reading UI file 'UI_variableGenerator.ui'
5
5
  ##
6
- ## Created by: Qt User Interface Compiler version 6.9.1
6
+ ## Created by: Qt User Interface Compiler version 6.9.2
7
7
  ##
8
8
  ## WARNING! All changes made in this file will be lost when recompiling UI file!
9
9
  ################################################################################
@@ -22,14 +22,12 @@ from excel2moodle import e2mMetadata, mainLogger
22
22
  from excel2moodle.core.category import Category
23
23
  from excel2moodle.core.dataStructure import QuestionDB
24
24
  from excel2moodle.core.exceptions import InvalidFieldException
25
- from excel2moodle.core.question import ParametricQuestion
25
+ from excel2moodle.core.question import ParametricQuestion, Question
26
26
  from excel2moodle.core.settings import Settings, Tags
27
+ from excel2moodle.extra.equationChecker import EqCheckerWindow
27
28
  from excel2moodle.extra.variableGenerator import VariableGeneratorDialog
28
29
  from excel2moodle.logger import LogWindowHandler
29
- from excel2moodle.question_types.mc import MCQuestion
30
- from excel2moodle.question_types.nf import NFQuestion
31
30
  from excel2moodle.ui import dialogs
32
- from excel2moodle.ui.equationChecker import EqCheckerWindow
33
31
  from excel2moodle.ui.treewidget import CategoryItem, QuestionItem
34
32
  from excel2moodle.ui.UI_mainWindow import Ui_MoodleTestGenerator
35
33
 
@@ -53,7 +51,8 @@ class MainWindow(QMainWindow):
53
51
  self.ui.setupUi(self)
54
52
  self.exportDialog = dialogs.ExportDialog(self)
55
53
  self.questionPreview = dialogs.QuestionPreview(self)
56
- self.eqChecker = EqCheckerWindow()
54
+ self.eqChecker = EqCheckerWindow(self)
55
+ self.eqChecker.setModal(False)
57
56
  self.connectEvents()
58
57
  logger.info("Settings are stored under: %s", self.qSettings.fileName())
59
58
  self.ui.treeWidget.setSelectionMode(QAbstractItemView.MultiSelection)
@@ -155,6 +154,15 @@ class MainWindow(QMainWindow):
155
154
  self.settings.get(Tags.QUESTIONVARIANT),
156
155
  )
157
156
 
157
+ @property
158
+ def currentQuestion(self) -> Question | None:
159
+ """Get the current question."""
160
+ item = self.ui.treeWidget.currentItem()
161
+ if isinstance(item, QuestionItem):
162
+ return item.question
163
+ logger.info("No Question Item selected.")
164
+ return None
165
+
158
166
  @Slot()
159
167
  def onSelectionChanged(self, **args) -> None:
160
168
  """Whenever the selection changes the total of selected points needs to be recalculated."""
@@ -166,8 +174,9 @@ class MainWindow(QMainWindow):
166
174
  count += q.question.points
167
175
  self.ui.pointCounter.setValue(count)
168
176
  self.ui.questionCounter.setValue(questions)
169
- if self.eqChecker.isVisible():
170
- self.openEqCheckerDlg()
177
+ # This would automatically update the question of the checker
178
+ # if self.eqChecker.isVisible():
179
+ # self.openEqCheckerDlg()
171
180
 
172
181
  @Slot()
173
182
  def toggleQuestionSelectionState(self, state) -> None:
@@ -249,11 +258,9 @@ class MainWindow(QMainWindow):
249
258
 
250
259
  @Slot()
251
260
  def updateQuestionPreview(self) -> None:
252
- item = self.ui.treeWidget.currentItem()
253
- if isinstance(item, QuestionItem):
254
- self.questionPreview.setupQuestion(item.question)
255
- else:
256
- logger.info("current Item is not a Question, can't preview")
261
+ question = self.currentQuestion
262
+ if question is not None:
263
+ self.questionPreview.setupQuestion(question)
257
264
 
258
265
  def setStatus(self, status) -> None:
259
266
  self.ui.statusbar.clearMessage()
@@ -261,17 +268,15 @@ class MainWindow(QMainWindow):
261
268
 
262
269
  @Slot()
263
270
  def openEqCheckerDlg(self) -> None:
264
- item = self.ui.treeWidget.currentItem()
265
- if isinstance(item, QuestionItem):
266
- question = item.question
267
- if isinstance(question, (NFQuestion, MCQuestion)):
268
- logger.debug("Can't check an MC or NF Question")
269
- else:
270
- logger.debug("opening wEquationChecker \n")
271
- self.eqChecker.setup(item.question)
272
- self.eqChecker.show()
271
+ question = self.currentQuestion
272
+ if question is None:
273
+ return
274
+ if isinstance(question, ParametricQuestion):
275
+ logger.debug("opening wEquationChecker \n")
276
+ self.eqChecker.show()
277
+ self.eqChecker.updateQuestion()
273
278
  else:
274
- logger.debug("No Question Item selected: %s", type(item))
279
+ logger.debug("Can't check an MC or NF Question")
275
280
 
276
281
  @Slot()
277
282
  def openAboutDlg(self) -> None:
@@ -286,24 +291,21 @@ class MainWindow(QMainWindow):
286
291
 
287
292
  @Slot()
288
293
  def openVariableGeneratorDlg(self) -> None:
289
- item = self.ui.treeWidget.currentItem()
290
- if isinstance(item, QuestionItem):
291
- question = item.question
292
- if isinstance(question, ParametricQuestion):
293
- dialog = VariableGeneratorDialog(self, parametrics=question.parametrics)
294
- if dialog.exec():
295
- self.questionPreview.setupQuestion(question)
296
- self.treeRefreshCategory(question.category)
297
- logger.info("Updated QuestionItem display for %s", question.id)
298
- self.copyVariablesToClipboard(
299
- variables=question.parametrics.variables
300
- )
301
- else:
302
- logger.warning("No variable sets were generated.")
294
+ question = self.currentQuestion
295
+ if question is None:
296
+ return
297
+ if isinstance(question, ParametricQuestion):
298
+ dialog = VariableGeneratorDialog(self, parametrics=question.parametrics)
299
+ dialog.setModal(False)
300
+ if dialog.exec():
301
+ self.questionPreview.setupQuestion(question)
302
+ self.treeRefreshCategory(question.category)
303
+ logger.info("Updated QuestionItem display for %s", question.id)
304
+ self.copyVariablesToClipboard(variables=question.parametrics.variables)
303
305
  else:
304
- logger.info("Selected item is not a ParametricQuestion.")
306
+ logger.warning("No variable sets were generated.")
305
307
  else:
306
- logger.info("No Question Item selected.")
308
+ logger.info("Selected item is not a ParametricQuestion.")
307
309
 
308
310
  @Slot()
309
311
  def copyVariablesToClipboard(
@@ -312,11 +314,11 @@ class MainWindow(QMainWindow):
312
314
  if variables is None:
313
315
  variables = {}
314
316
  if not variables:
315
- item = self.ui.treeWidget.currentItem()
316
- if isinstance(item, QuestionItem):
317
- question = item.question
318
- if isinstance(question, ParametricQuestion):
319
- variables = question.parametrics.variables
317
+ question = self.currentQuestion
318
+ if question is None:
319
+ return
320
+ if isinstance(question, ParametricQuestion):
321
+ variables = question.parametrics.variables
320
322
  varsList = [
321
323
  f"{name}\t{'; '.join(map(str, vals))}"
322
324
  for name, vals in variables.items()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: excel2moodle
3
- Version: 0.6.5
3
+ Version: 0.7.0
4
4
  Summary: A package for converting questions from a spreadsheet, to valid moodle-xml
5
5
  Author: Jakob Bosse
6
6
  License-Expression: GPL-3.0-or-later
@@ -90,6 +90,21 @@ If You want to support my work as well, you can by me a [coffee](https://ko-fi.c
90
90
 
91
91
  # Changelogs
92
92
 
93
+ ## 0.7.0 (2025-09-30)
94
+ Rework of the equation checker done!
95
+
96
+ ### feature (1 change)
97
+
98
+ - [finalized equation Checker](https://gitlab.com/jbosse3/excel2moodle/-/commit/55e3891d3da56357ad00f672a86c2690d551d21c)
99
+
100
+ ### documentation (1 change)
101
+
102
+ - [Documented feedback usages](https://gitlab.com/jbosse3/excel2moodle/-/commit/6f50ce023a3235b3f34b6272a4ce5057346f8751)
103
+
104
+ ### improvement (1 change)
105
+
106
+ - [MainWindow got a currentQuestion property](https://gitlab.com/jbosse3/excel2moodle/-/commit/59b18e158201357b767a36dab0f300f88cb5e9ad)
107
+
93
108
  ## 0.6.5 (2025-09-02)
94
109
  Added Scripted Media Support now with the module
95
110
 
@@ -23,7 +23,7 @@ excel2moodle/core/settings.py
23
23
  excel2moodle/core/stringHelpers.py
24
24
  excel2moodle/core/validator.py
25
25
  excel2moodle/extra/__init__.py
26
- excel2moodle/extra/equationVerification.py
26
+ excel2moodle/extra/equationChecker.py
27
27
  excel2moodle/extra/scriptCaller.py
28
28
  excel2moodle/extra/updateQuery.py
29
29
  excel2moodle/extra/variableGenerator.py
@@ -41,7 +41,6 @@ excel2moodle/ui/UI_variantDialog.py
41
41
  excel2moodle/ui/__init__.py
42
42
  excel2moodle/ui/appUi.py
43
43
  excel2moodle/ui/dialogs.py
44
- excel2moodle/ui/equationChecker.py
45
44
  excel2moodle/ui/treewidget.py
46
45
  test/test_bullets.py
47
46
  test/test_feedbacking.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "excel2moodle"
7
- version = "0.6.5"
7
+ version = "0.7.0"
8
8
  authors = [
9
9
  { name="Jakob Bosse" },
10
10
  ]
@@ -1,126 +0,0 @@
1
- """Script for verifying the equations written into the ``result`` field of NFM-type Question.
2
-
3
- This script does two things.
4
-
5
- #. It calculates all the answers obtained from the series of variables.
6
- #. It compares the calculation of the first answer to the ``firstResult`` field.
7
-
8
- Usage
9
- =====
10
-
11
- From the main UI
12
- ----------------
13
-
14
- #. Start this tool from the top bar in the main Window under the *Tools* section
15
- #. A new window will open inside you:
16
- #. Enter the Number of the Category
17
- #. Enter the Number of the Question
18
- #. Click on ``Run check now`` and Inspect the results
19
- #. Rinse and repeat
20
-
21
- As Script
22
- ---------
23
-
24
- #. Start this script with ``py -m excel2moodle.extra.equationVerification`` inside the top-level Directory
25
- #. Enter the Number of the Category
26
- #. Enter the Number of the Question
27
- #. Inspect the results
28
- #. Rinse and repeat
29
- """
30
-
31
- from pathlib import Path
32
-
33
- import pandas as pd
34
-
35
- # Hier Bitte die Frage angeben, die getestet Werden soll:
36
-
37
- # ===========================================================
38
-
39
-
40
- def checkResult(checkerValue: float, calculation: float, tolerance=0.01) -> bool:
41
- """Checks if the two Arguments are within the tolerance the same value.
42
-
43
- :param checkerValue: the value the calculation is compared against
44
- :type checkerValue: fleat
45
- :param calculation: the value to be compared against checker Value
46
- :type calculation: float
47
- :param tolerance: the standart tolerance is 0.01 -> 1%
48
- :type tolerance: float, optional
49
-
50
- :returns:
51
- True if checkerValue == calculation
52
- False if checkerValue != calculation
53
- :rtype: bool
54
- """
55
- upper = abs(checkerValue + checkerValue * tolerance)
56
- lower = abs(checkerValue - checkerValue * tolerance)
57
- return bool(abs(calculation) > lower and abs(calculation) < upper)
58
-
59
-
60
- def equationChecker(
61
- categoryName: str, qNumber: int, spreadsheetFile
62
- ) -> tuple[list[str], list[float], float]:
63
- """This Function calculates all Results an invokes the checkResult function.
64
-
65
- Parameters
66
- ----------
67
- categoryName : str
68
- The category in which the question to be tested is
69
- This must match a sheet name of the spreadsheet
70
- qNumber : int
71
- The number of the question which results are tested
72
- spreadsheetFile : Path
73
- The Filepath to the spreadsheet
74
-
75
- Returns
76
- -------
77
- bulletPointsString : list[str]
78
- The string list with the bullet points, with numeric values instead of variables
79
- results : list[str]
80
- The list with the calculated results
81
- checkerValue : float
82
- The value taken from the ``firstResult`` field
83
-
84
- """
85
- spreadsheetFile.resolve()
86
- df = pd.read_excel(spreadsheetFile, sheet_name=categoryName, index_col=0)
87
- eq = df.loc["result"][qNumber]
88
- bps = df.loc["bulletPoints"][qNumber]
89
- try:
90
- res = float(df.loc["firstResult"][qNumber])
91
- except Exception:
92
- res = 0
93
- bps, calcs = nmq.parseNumericMultiQuestion(df, bps, eq, qNumber)
94
- return bps, calcs, res
95
-
96
-
97
- def main(
98
- spreadsheetFile=Path("../Fragensammlung/Main_question_all.xlsx"),
99
- catN=None,
100
- qNumber=None,
101
- ) -> None:
102
- """Takes the Spreadsheet, and asks for a category and a question number."""
103
- if catN is None:
104
- catN = input("Geben Sie die Kategorie an: KAT_")
105
- categoryName = f"KAT_{catN}"
106
- if qNumber is None:
107
- qNumber = int(input("Geben Sie die Fragennummer an: "))
108
- bullets, results, firstResult = equationChecker(
109
- categoryName, qNumber, spreadsheetFile=spreadsheetFile
110
- )
111
- check = False
112
-
113
- for i, calculation in enumerate(results):
114
- if i == 0 and firstResult != 0:
115
- check = checkResult(firstResult, calculation)
116
-
117
- if check:
118
- pass
119
- else:
120
- pass
121
-
122
-
123
- if __name__ == "__main__":
124
- spreadsheet = input("Geben Sie den Pfad zu dem spreadsheet an:")
125
- while True:
126
- main(Path(spreadsheet))
@@ -1,70 +0,0 @@
1
- import logging
2
- import math
3
- from pathlib import Path
4
-
5
- from PySide6.QtWidgets import QWidget
6
-
7
- from excel2moodle import mainLogger
8
- from excel2moodle.core.question import ParametricQuestion
9
- from excel2moodle.core.settings import Tags
10
- from excel2moodle.logger import LogWindowHandler
11
- from excel2moodle.question_types.nfm import NFMQuestionParser
12
-
13
- from .UI_equationChecker import Ui_EquationChecker
14
-
15
- logger = logging.getLogger(__name__)
16
-
17
- loggerSignal = LogWindowHandler()
18
- mainLogger.addHandler(loggerSignal)
19
-
20
-
21
- class EqCheckerWindow(QWidget):
22
- def __init__(self) -> None:
23
- super().__init__()
24
- self.excelFile = Path()
25
- self.ui = Ui_EquationChecker()
26
- self.ui.setupUi(self)
27
- self.ui.buttonRunCheck.clicked.connect(
28
- lambda: self.updateCalculation(),
29
- )
30
- self.question: ParametricQuestion
31
-
32
- def updateCalculation(self) -> None:
33
- equation = self.ui.equationText.toPlainText()
34
- results: list[float] = []
35
- firstResult = self.question.rawData.get(Tags.FIRSTRESULT)
36
- for i in range(self.question.variants):
37
- NFMQuestionParser.setupAstIntprt(self.question.variables, i)
38
- results.append(float(NFMQuestionParser.astEval(equation)))
39
- check: bool = False
40
- self.ui.textResultsOutput.insertHtml(f"<hr><br><h2>{equation:^30}</h2><br>")
41
- for i, calculation in enumerate(results):
42
- if i == 0 and firstResult != 0:
43
- check = bool(math.isclose(calculation, firstResult, rel_tol=0.01))
44
- self.ui.lineCalculatedRes.setText(f"{calculation}")
45
- self.ui.textResultsOutput.append(f"<h3>Result {check = }</h3><br>")
46
- self.ui.textResultsOutput.append(
47
- f"Ergebnis {i + 1}: \t{calculation}",
48
- )
49
- if check:
50
- self.ui.lineCheckResult.setText("[OK]")
51
- logger.info(
52
- " [OK] The first calculated result matches 'firstResult'",
53
- )
54
- else:
55
- self.ui.lineCheckResult.setText("[ERROR]")
56
- logger.warning(
57
- "The first calculated result does not match 'firstResult'",
58
- )
59
-
60
- def setup(self, question: ParametricQuestion) -> None:
61
- self.question = question
62
- self.ui.textResultsOutput.clear()
63
- self.ui.equationText.clear()
64
- bullets = question.rawData.get(Tags.BPOINTS)
65
- firstResult = question.rawData.get(Tags.FIRSTRESULT)
66
- self.ui.lineFirstResult.setText(str(firstResult))
67
- self.ui.equationText.appendPlainText(question.rawData.get(Tags.EQUATION))
68
- for bullet in bullets:
69
- self.ui.textResultsOutput.append(bullet)
70
- self.updateCalculation()
File without changes
File without changes