From 11beed44c78847c91b25d8b4c9d8b3c7ada8de35 Mon Sep 17 00:00:00 2001
From: hbui <hong-phuc.bui@htwsaar.de>
Date: Thu, 25 Jul 2024 03:01:12 +0200
Subject: [PATCH] Auswahl der Methode is eindeutig gestaltet

---
 num-int/src/numint/guimain.py           |   33 +++++++++-
 num-int/src/numint/mainwindow.ui        |   40 ++++++++++++-
 stundenplan/src/pygraph/graphdemo.py    |   15 +++--
 num-int/src/numint/ui_mainwindow.py     |   41 +++++++++++--
 num-int/src/numint/riemann_sum.py       |   21 ++++++
 num-int/tests/numint/expression_test.py |   29 ++++++++-
 6 files changed, 149 insertions(+), 30 deletions(-)

diff --git a/num-int/src/numint/guimain.py b/num-int/src/numint/guimain.py
index 3f90199..076d851 100644
--- a/num-int/src/numint/guimain.py
+++ b/num-int/src/numint/guimain.py
@@ -35,24 +35,30 @@
         layout.addWidget(self.canvas)
         self.ui.plotBox.setLayout(layout)
         self.ui.plotBtn.clicked.connect(self._update_plot)
+        self.ui.breakMethod.buttonClicked.connect(self._activate_break_rule)
+        self.ui.numberOfSectionsMethod.click()
 
     def _update_plot(self):
         fn_expr = self.ui.function.text()
         self.fn_expr = fn_expr
         start = self.ui.startValue.text()
         end = self.ui.endValue.text()
-        epsilon = self.ui.espilon.text()
+
         try:
             f = parse_function(fn_expr)
             (a, b) = (parse_value(start), parse_value(end))
-            if epsilon is not None and len(epsilon.strip()) > 0:
-                eps = parse_value(epsilon)
+            method_id = self.ui.breakMethod.checkedId()
+            if method_id == self.ui.breakMethod.id(self.ui.minEpsilonMethod):
+                epsilon = self.ui.espilon.text()
+                eps = abs(parse_value(epsilon))
+                self.ui.espilon.setText(f"{eps}")
                 print(f"plot f(x) = {fn_expr}, {a}, {b}, epsilon = {eps}")
                 (self.x, self.y, self.left, self.right, self.num_of_iterations, *_) = numint_epsilon(f, a, b, eps)
                 self._update_plot_eps()
-            else:
+            elif method_id == self.ui.breakMethod.id(self.ui.numberOfSectionsMethod):
                 section = self.ui.section.text()
-                sec = parse_value(section)
+                sec = int(abs(parse_value(section)))
+                self.ui.section.setText(f"{sec}")
                 print(f"plot f(x) = {fn_expr}, {a}, {b}, section = {sec}")
                 (self.x, self.y, self.left, self.right, self.num_of_iterations, *_) = numint_section(f, a, b, sec)
                 self._update_plot_eps()
@@ -74,6 +80,23 @@
         self.ui.rightSum.setText(f"{self.right}")
         self.ui.numOfSections.setText(f"{self.num_of_iterations}")
 
+    def _activate_break_rule(self):
+        method_id = self.ui.breakMethod.checkedId()
+        print(method_id)
+        if method_id == self.ui.breakMethod.id(self.ui.numberOfSectionsMethod):
+            print("activate num of sec")
+            self.ui.section.setEnabled(True)
+            self.ui.section.setFocus()
+            self.ui.espilon.setEnabled(False)
+
+        elif method_id == self.ui.breakMethod.id(self.ui.minEpsilonMethod):
+            print("activate minimum epsilon method")
+            self.ui.section.setEnabled(False)
+            self.ui.espilon.setEnabled(True)
+            self.ui.espilon.setFocus()
+
+
+
 
 def main():
     app = QApplication(sys.argv)
diff --git a/num-int/src/numint/mainwindow.ui b/num-int/src/numint/mainwindow.ui
index c5069ba..8f1f47f 100644
--- a/num-int/src/numint/mainwindow.ui
+++ b/num-int/src/numint/mainwindow.ui
@@ -101,14 +101,14 @@
          <string>Abbuchkriterium</string>
         </property>
         <layout class="QFormLayout" name="formLayout_2">
-         <item row="0" column="0">
+         <item row="2" column="0">
           <widget class="QLabel" name="label_4">
            <property name="text">
             <string>Epsilon</string>
            </property>
           </widget>
          </item>
-         <item row="0" column="1">
+         <item row="2" column="1">
           <widget class="QLineEdit" name="espilon">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@@ -118,14 +118,14 @@
            </property>
           </widget>
          </item>
-         <item row="1" column="0">
+         <item row="3" column="0">
           <widget class="QLabel" name="label_5">
            <property name="text">
             <string>Anzahl der Sektionen</string>
            </property>
           </widget>
          </item>
-         <item row="1" column="1">
+         <item row="3" column="1">
           <widget class="QLineEdit" name="section">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@@ -138,6 +138,35 @@
            </property>
           </widget>
          </item>
+         <item row="0" column="1">
+          <widget class="QGroupBox" name="breakMethodBox">
+           <property name="title">
+            <string>Methoden</string>
+           </property>
+           <layout class="QHBoxLayout" name="horizontalLayout">
+            <item>
+             <widget class="QRadioButton" name="minEpsilonMethod">
+              <property name="text">
+               <string>Minimale Epsilon</string>
+              </property>
+              <attribute name="buttonGroup">
+               <string notr="true">breakMethod</string>
+              </attribute>
+             </widget>
+            </item>
+            <item>
+             <widget class="QRadioButton" name="numberOfSectionsMethod">
+              <property name="text">
+               <string>Anzahl der Sektionen</string>
+              </property>
+              <attribute name="buttonGroup">
+               <string notr="true">breakMethod</string>
+              </attribute>
+             </widget>
+            </item>
+           </layout>
+          </widget>
+         </item>
         </layout>
        </widget>
       </item>
@@ -254,4 +283,7 @@
  </widget>
  <resources/>
  <connections/>
+ <buttongroups>
+  <buttongroup name="breakMethod"/>
+ </buttongroups>
 </ui>
diff --git a/num-int/src/numint/riemann_sum.py b/num-int/src/numint/riemann_sum.py
index 250f073..f0b997d 100644
--- a/num-int/src/numint/riemann_sum.py
+++ b/num-int/src/numint/riemann_sum.py
@@ -17,7 +17,16 @@
     pass
 
 
-def numint_epsilon(f:Callable[[float], float], a: float, b: float, epsilon: float = 1e-3):
+def numint_epsilon(f: Callable[[float], float], a: float, b: float, epsilon: float = 1e-3):
+    """
+    a not very stupid implementation of Riemann sum for a function,
+    left sum and right sum are calculated as long as their difference less than the given epsilon.
+    :param f:
+    :param a:
+    :param b:
+    :param epsilon:
+    :return:
+    """
     dx = b - a
     x = [a, b]  # debug only
     y = [f(a), f(b)]
@@ -36,7 +45,15 @@
     return x, y, s_left, s_right, n
 
 
-def numint_section(f:Callable[[float], float], a: float, b: float, section_count: int = 8):
+def numint_section(f: Callable[[float], float], a: float, b: float, section_count: int = 8):
+    """
+    a stupid implementation of Riemann sum for a function with a fixed number of sections in interval [a, b]
+    :param f:
+    :param a:
+    :param b:
+    :param section_count:
+    :return:
+    """
     dx = b - a
     x = [a, b]
     y = [f(a), f(b)]
diff --git a/num-int/src/numint/ui_mainwindow.py b/num-int/src/numint/ui_mainwindow.py
index b47fd6b..84d39bb 100644
--- a/num-int/src/numint/ui_mainwindow.py
+++ b/num-int/src/numint/ui_mainwindow.py
@@ -15,10 +15,11 @@
     QFont, QFontDatabase, QGradient, QIcon,
     QImage, QKeySequence, QLinearGradient, QPainter,
     QPalette, QPixmap, QRadialGradient, QTransform)
-from PySide6.QtWidgets import (QApplication, QFormLayout, QGroupBox, QHBoxLayout,
-    QLabel, QLineEdit, QMainWindow, QMenuBar,
-    QPlainTextEdit, QPushButton, QSizePolicy, QSpacerItem,
-    QStatusBar, QVBoxLayout, QWidget)
+from PySide6.QtWidgets import (QApplication, QButtonGroup, QFormLayout, QGroupBox,
+    QHBoxLayout, QLabel, QLineEdit, QMainWindow,
+    QMenuBar, QPlainTextEdit, QPushButton, QRadioButton,
+    QSizePolicy, QSpacerItem, QStatusBar, QVBoxLayout,
+    QWidget)
 
 class Ui_MainWindow(object):
     def setupUi(self, MainWindow):
@@ -89,7 +90,7 @@
         self.label_4 = QLabel(self.breakRule)
         self.label_4.setObjectName(u"label_4")
 
-        self.formLayout_2.setWidget(0, QFormLayout.LabelRole, self.label_4)
+        self.formLayout_2.setWidget(2, QFormLayout.LabelRole, self.label_4)
 
         self.espilon = QLineEdit(self.breakRule)
         self.espilon.setObjectName(u"espilon")
@@ -99,19 +100,40 @@
         sizePolicy1.setHeightForWidth(self.espilon.sizePolicy().hasHeightForWidth())
         self.espilon.setSizePolicy(sizePolicy1)
 
-        self.formLayout_2.setWidget(0, QFormLayout.FieldRole, self.espilon)
+        self.formLayout_2.setWidget(2, QFormLayout.FieldRole, self.espilon)
 
         self.label_5 = QLabel(self.breakRule)
         self.label_5.setObjectName(u"label_5")
 
-        self.formLayout_2.setWidget(1, QFormLayout.LabelRole, self.label_5)
+        self.formLayout_2.setWidget(3, QFormLayout.LabelRole, self.label_5)
 
         self.section = QLineEdit(self.breakRule)
         self.section.setObjectName(u"section")
         sizePolicy1.setHeightForWidth(self.section.sizePolicy().hasHeightForWidth())
         self.section.setSizePolicy(sizePolicy1)
 
-        self.formLayout_2.setWidget(1, QFormLayout.FieldRole, self.section)
+        self.formLayout_2.setWidget(3, QFormLayout.FieldRole, self.section)
+
+        self.breakMethodBox = QGroupBox(self.breakRule)
+        self.breakMethodBox.setObjectName(u"breakMethodBox")
+        self.horizontalLayout = QHBoxLayout(self.breakMethodBox)
+        self.horizontalLayout.setObjectName(u"horizontalLayout")
+        self.minEpsilonMethod = QRadioButton(self.breakMethodBox)
+        self.breakMethod = QButtonGroup(MainWindow)
+        self.breakMethod.setObjectName(u"breakMethod")
+        self.breakMethod.addButton(self.minEpsilonMethod)
+        self.minEpsilonMethod.setObjectName(u"minEpsilonMethod")
+
+        self.horizontalLayout.addWidget(self.minEpsilonMethod)
+
+        self.numberOfSectionsMethod = QRadioButton(self.breakMethodBox)
+        self.breakMethod.addButton(self.numberOfSectionsMethod)
+        self.numberOfSectionsMethod.setObjectName(u"numberOfSectionsMethod")
+
+        self.horizontalLayout.addWidget(self.numberOfSectionsMethod)
+
+
+        self.formLayout_2.setWidget(0, QFormLayout.FieldRole, self.breakMethodBox)
 
 
         self.verticalLayout.addWidget(self.breakRule)
@@ -216,6 +238,9 @@
         self.label_4.setText(QCoreApplication.translate("MainWindow", u"Epsilon", None))
         self.label_5.setText(QCoreApplication.translate("MainWindow", u"Anzahl der Sektionen", None))
         self.section.setText(QCoreApplication.translate("MainWindow", u"8", None))
+        self.breakMethodBox.setTitle(QCoreApplication.translate("MainWindow", u"Methoden", None))
+        self.minEpsilonMethod.setText(QCoreApplication.translate("MainWindow", u"Minimale Epsilon", None))
+        self.numberOfSectionsMethod.setText(QCoreApplication.translate("MainWindow", u"Anzahl der Sektionen", None))
         self.plotBtn.setText(QCoreApplication.translate("MainWindow", u"Ok", None))
         self.riemannSumGruppe.setTitle(QCoreApplication.translate("MainWindow", u"Riemann Summe", None))
         self.label.setText(QCoreApplication.translate("MainWindow", u"linke Summe", None))
diff --git a/num-int/tests/numint/expression_test.py b/num-int/tests/numint/expression_test.py
index 1846d74..7301169 100644
--- a/num-int/tests/numint/expression_test.py
+++ b/num-int/tests/numint/expression_test.py
@@ -9,27 +9,46 @@
 
     def test_prio_product_exponent(self):
         parser = Lark_StandAlone()
-        tree = parser.parse("x ** -3 * sin(12)")  # => (x^3) * sin(12)
-        print(tree.pretty())
+        tree = parser.parse("x ** -3 * sin(12)")
+        self.assertEqual('''mul
+  exponent
+    var	x
+    neg
+      number	3
+  function
+    sin
+    argv
+      number	12
+''', tree.pretty(indent_str='  '))
 
     def test_prio_product_exponent_revert(self):
         parser = Lark_StandAlone()
         tree = parser.parse("sin(12) * x ** sqrt(4)")  # => sin(12) * (x ** sqrt(4))
-        print(tree.pretty())
+        print(f">{tree.pretty()}<")
+        self.assertEqual('''mul
+  function
+    sin
+    argv
+      number	12
+  exponent
+    var	x
+    function
+      sqrt
+      argv
+        number	4
+''', tree.pretty(indent_str='  '))
 
     def test_use_transform(self):
         parser = Lark_StandAlone(transformer=ExpressionTransformer())
         tree = parser.parse("log(-12, 5) * x ** sqrt(4)")  # => sin(12) * (x^sqrt(4))
         self.assertEqual(tree, 'math.log(-12, 5) * x ** math.sqrt(4)')
 
-        print(tree)
 
     def test_use_function_in_function(self):
         parser = Lark_StandAlone(transformer=ExpressionTransformer())
         tree = parser.parse("tan(radians(x))")  # =>
         self.assertEqual(tree, 'math.tan(math.radians(x))')
 
-        print(tree)
 
 
 
diff --git a/stundenplan/src/pygraph/graphdemo.py b/stundenplan/src/pygraph/graphdemo.py
index 2371fd4..c0e3df9 100644
--- a/stundenplan/src/pygraph/graphdemo.py
+++ b/stundenplan/src/pygraph/graphdemo.py
@@ -1,3 +1,6 @@
+from typing import Any, Callable
+
+
 class Graph:
     def __init__(self):
         self._adjacent: dict[int, set] = {}
@@ -41,7 +44,7 @@
         return self
         pass
 
-    def get_attribute(self, vertex):
+    def get_attribute(self, vertex: int):
         if vertex in self._adjacent:
             return self._vertex_attribute[vertex]
         else:
@@ -51,16 +54,16 @@
     def vertices(self):
         return self._adjacent.keys()
 
-    def for_each_vertices(self, action):
+    def for_each_vertices(self, action: Callable[[int], Any]):
         for v in self.vertices():
             action(v)
 
-    def adjacent_of(self, vertex):
+    def adjacent_of(self, vertex: int):
         if vertex not in self._adjacent:
             raise ValueError(f"Graph does not include vertex {vertex}")
         return self._adjacent.get(vertex)
 
-    def for_each_edges(self, action):
+    def for_each_edges(self, action: Callable[[int, int], Any]):
         visited_edges: dict[int, set] = {}
         for start in self.vertices():
             for end in self.adjacent_of(start):
@@ -76,10 +79,10 @@
                 adjacent.add(second)
                 action(start, end)
 
-    def get_lecture_name(self, vertex):
+    def get_lecture_name(self, vertex: int):
         pass
 
-    def set_lecture_name(self, vertex, name):
+    def set_lecture_name(self, vertex: int, name: str):
         pass
 
     def __repr__(self):

--
Gitblit v1.10.0-SNAPSHOT