hbui
2024-07-25 11beed44c78847c91b25d8b4c9d8b3c7ada8de35
Auswahl der Methode is eindeutig gestaltet
6 files modified
179 ■■■■ changed files
num-int/src/numint/guimain.py 33 ●●●● patch | view | raw | blame | history
num-int/src/numint/mainwindow.ui 40 ●●●●● patch | view | raw | blame | history
num-int/src/numint/riemann_sum.py 21 ●●●●● patch | view | raw | blame | history
num-int/src/numint/ui_mainwindow.py 41 ●●●● patch | view | raw | blame | history
num-int/tests/numint/expression_test.py 29 ●●●● patch | view | raw | blame | history
stundenplan/src/pygraph/graphdemo.py 15 ●●●●● patch | view | raw | blame | history
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)
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>
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)]
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))
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)
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):