hbui
2024-07-21 f12ecb67472aa2453d3b1b3fb68e4eb9521aee77
gui ok
4 files modified
1 files added
1 files renamed
1 files deleted
534 ■■■■ changed files
num-int/src/numint/guimain.py 58 ●●●●● patch | view | raw | blame | history
num-int/src/numint/main.py 16 ●●●●● patch | view | raw | blame | history
num-int/src/numint/mainwindow.ui 201 ●●●● patch | view | raw | blame | history
num-int/src/numint/riemann_sum.py 28 ●●●● patch | view | raw | blame | history
num-int/src/numint/ui_mainwindow.py 161 ●●●● patch | view | raw | blame | history
num-int/test/numint/RiemannSum_test.py 32 ●●●●● patch | view | raw | blame | history
num-int/test/numint/riemann_sum_test.py 38 ●●●●● patch | view | raw | blame | history
num-int/src/numint/guimain.py
@@ -1,8 +1,22 @@
import sys
import matplotlib
from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout
from numint.input_parser import parse_function, parse_value
from numint.riemann_sum import numint_epsilon, numint_section
from numint.ui_mainwindow import Ui_MainWindow
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
matplotlib.use('QtAgg')
class MplCanvas(FigureCanvasQTAgg):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)
        super(MplCanvas, self).__init__(fig)
class MainWindow(QMainWindow):
@@ -10,6 +24,47 @@
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.canvas = MplCanvas(self)
        self._update_plot()
        toolbar = NavigationToolbar(self.canvas, self)
        layout = QVBoxLayout()
        layout.addWidget(toolbar)
        layout.addWidget(self.canvas)
        self.ui.plotBox.setLayout(layout)
        self.ui.plotBtn.clicked.connect(self._update_plot)
    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)
                print(f"plot {fn_expr}, {a}, {b}, epsilon = {eps}")
                (self.x, self.y, *_) = numint_epsilon(f, a, b, eps)
                self._update_plot_eps()
            else:
                section = self.ui.section.text()
                sec = parse_value(section)
                print(f"plot f(x) = {fn_expr}, {a}, {b}, section = {sec}")
                (self.x, self.y, *_) = numint_section(f, a, b, sec)
                self._update_plot_eps()
        except Exception as ex:
            print(ex)
            pass
    def _update_plot_eps(self):
        self.canvas.axes.cla()  # Clear the canvas.
        self.canvas.axes.stairs(self.y[1:],   self.x, baseline=0, fill=True, alpha=0.5, label=self.fn_expr)
        self.canvas.axes.stairs(self.y[0:-1], self.x, baseline=0, fill=True, alpha=0.5, label=self.fn_expr)
        self.canvas.axes.plot(self.x, self.y, color="black")
        self.canvas.draw()
def main():
@@ -22,4 +77,3 @@
if __name__ == "__main__":
    main()
num-int/src/numint/main.py
@@ -1,7 +1,7 @@
import sys
from matplotlib import pyplot as plt
from numint.RiemannSum import numint
from numint.riemann_sum import numint_epsilon
from numint.input_parser import parse_function, parse_value
@@ -10,11 +10,15 @@
    (a, b) = (parse_value(start), parse_value(end))
    eps = parse_value(epsilon)
    (x, y, l, r, n) = numint(f, a, b, eps)
    # print(l, r, n)
    plt.step(x, y, label="x^3")
    plt.step(x, y, where="post", label="x^3")
    plt.plot(x, y, color="gray", alpha=0.3)
    (x, y, l, r, n) = numint_epsilon(f, a, b, eps)
    fig, ax = plt.subplots()
    ax.stairs(y[1:], x, baseline=0, fill=True, alpha=1,label=function_expr)
    ax.stairs(y[0:-1], x, baseline=0, fill=True, color="orange", alpha=0.5, label=function_expr)
    #ax.step(x, y, label=function_expr)
    #ax.step(x, y, where="post", label=function_expr)
    ax.plot(x, y, color="black")
    plt.show()
    pass
num-int/src/numint/mainwindow.ui
@@ -18,65 +18,55 @@
    <item>
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout">
        <item>
         <widget class="QLabel" name="label_3">
          <property name="text">
           <string>Funktion</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QComboBox" name="functions">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <item>
       <widget class="QGroupBox" name="functionInfo">
        <property name="title">
         <string>Angabe der Funktion</string>
        </property>
        <layout class="QHBoxLayout" name="horizontalLayout">
         <item>
          <widget class="QLabel" name="label_start">
           <property name="text">
            <string>sin</string>
            <string>Funktion f(x) = </string>
           </property>
          </item>
          <item>
          </widget>
         </item>
         <item>
          <widget class="QLineEdit" name="function">
           <property name="text">
            <string>cos</string>
            <string>x ** 2</string>
           </property>
          </item>
          <item>
          </widget>
         </item>
         <item>
          <widget class="QLabel" name="label_fn">
           <property name="text">
            <string>x^2</string>
            <string>start</string>
           </property>
          </item>
          <item>
          </widget>
         </item>
         <item>
          <widget class="QLineEdit" name="startValue">
           <property name="text">
            <string>x^3</string>
            <string>0</string>
           </property>
          </item>
         </widget>
        </item>
        <item>
         <widget class="QLabel" name="label">
          <property name="text">
           <string>start</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QLineEdit" name="startValue"/>
        </item>
        <item>
         <widget class="QLabel" name="label_2">
          <property name="text">
           <string>end</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QLineEdit" name="endValue"/>
        </item>
       </layout>
          </widget>
         </item>
         <item>
          <widget class="QLabel" name="label_end">
           <property name="text">
            <string>end</string>
           </property>
          </widget>
         </item>
         <item>
          <widget class="QLineEdit" name="endValue">
           <property name="text">
            <string>4</string>
           </property>
          </widget>
         </item>
        </layout>
       </widget>
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_2">
@@ -94,7 +84,7 @@
         </spacer>
        </item>
        <item>
         <widget class="QPushButton" name="pushButton">
         <widget class="QPushButton" name="plotBtn">
          <property name="text">
           <string>Ok</string>
          </property>
@@ -102,10 +92,115 @@
        </item>
       </layout>
      </item>
      <item>
       <widget class="QPlainTextEdit" name="plainTextEdit">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="font">
         <font>
          <family>Noto Mono</family>
         </font>
        </property>
        <property name="readOnly">
         <bool>true</bool>
        </property>
        <property name="plainText">
         <string>Die Funktion f(x) kann eine belibige Kombination von arithmetischen Operationen und Python mathematische Funktion in Modul math sein. Einige Beispiele sind:
x ** 2
x ** 3
tan(radians(x))</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
     <widget class="QGroupBox" name="groupBox">
     <widget class="QGroupBox" name="breakRule">
      <property name="title">
       <string>Abbuchkriterium</string>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout_3">
       <item>
        <layout class="QHBoxLayout" name="horizontalLayout_5">
         <item>
          <widget class="QLabel" name="label_4">
           <property name="text">
            <string>Maximum Differenz ziwschen Link- und Recht-Summe</string>
           </property>
          </widget>
         </item>
         <item>
          <spacer name="horizontalSpacer_2">
           <property name="orientation">
            <enum>Qt::Orientation::Horizontal</enum>
           </property>
           <property name="sizeHint" stdset="0">
            <size>
             <width>40</width>
             <height>20</height>
            </size>
           </property>
          </spacer>
         </item>
         <item>
          <widget class="QLineEdit" name="espilon">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
             <horstretch>0</horstretch>
             <verstretch>0</verstretch>
            </sizepolicy>
           </property>
          </widget>
         </item>
        </layout>
       </item>
       <item>
        <layout class="QHBoxLayout" name="horizontalLayout_3">
         <item>
          <widget class="QLabel" name="label_5">
           <property name="text">
            <string>Anzahl der Sektionen</string>
           </property>
          </widget>
         </item>
         <item>
          <spacer name="horizontalSpacer_3">
           <property name="orientation">
            <enum>Qt::Orientation::Horizontal</enum>
           </property>
           <property name="sizeHint" stdset="0">
            <size>
             <width>40</width>
             <height>20</height>
            </size>
           </property>
          </spacer>
         </item>
         <item>
          <widget class="QLineEdit" name="section">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
             <horstretch>0</horstretch>
             <verstretch>0</verstretch>
            </sizepolicy>
           </property>
           <property name="text">
            <string>8</string>
           </property>
          </widget>
         </item>
        </layout>
       </item>
      </layout>
     </widget>
    </item>
    <item>
     <widget class="QGroupBox" name="plotBox">
      <property name="enabled">
       <bool>true</bool>
      </property>
num-int/src/numint/riemann_sum.py
File was renamed from num-int/src/numint/RiemannSum.py
@@ -1,3 +1,6 @@
from typing import Callable
def split(iteration=8):
    (a, b) = (0, 8)
    x = [a, b]
@@ -14,7 +17,7 @@
    pass
def numint(f, a, b, epsilon=1e-3):
def numint_epsilon(f:Callable[[float], float], a: float, b: float, epsilon: float = 1e-3):
    dx = b - a
    x = [a, b]  # debug only
    y = [f(a), f(b)]
@@ -25,7 +28,6 @@
        parts = 2 * parts
        dx = dx / 2
        n += 1
        # print(n, " â†’ ", parts)
        for i in range(1, parts, 2):
            x.insert(i, a + i * dx)
            y.insert(i, f(a + i * dx))
@@ -34,7 +36,27 @@
    return x, y, s_left, s_right, n
def numint_compact(f, a, b, epsilon=1e-3):
def numint_section(f:Callable[[float], float], a: float, b: float, section_count: int = 8):
    dx = b - a
    x = [a, b]
    y = [f(a), f(b)]
    (n, parts) = (0, 1)
    s_left = dx * y[0]
    s_right = dx * y[1]
    while parts < section_count:
        parts = 2 * parts
        dx = dx / 2
        n += 1
        for i in range(1, parts, 2):
            x.insert(i, a + i * dx)
            y.insert(i, f(a + i * dx))
        s_left = sum(y[0:-1]) * dx
        s_right = sum(y[1:]) * dx
        pass
    return x, y, s_left, s_right, n
def numint_compact(f: Callable[[float], float], a: float, b: float, epsilon=1e-3):
    dx = b - a
    y_l = f(a)
    y_r = f(b)
num-int/src/numint/ui_mainwindow.py
@@ -15,8 +15,8 @@
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QComboBox, QGroupBox, QHBoxLayout,
    QLabel, QLineEdit, QMainWindow, QMenuBar,
from PySide6.QtWidgets import (QApplication, QGroupBox, QHBoxLayout, QLabel,
    QLineEdit, QMainWindow, QMenuBar, QPlainTextEdit,
    QPushButton, QSizePolicy, QSpacerItem, QStatusBar,
    QVBoxLayout, QWidget)
@@ -31,49 +31,42 @@
        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.horizontalLayout = QHBoxLayout()
        self.functionInfo = QGroupBox(self.centralwidget)
        self.functionInfo.setObjectName(u"functionInfo")
        self.horizontalLayout = QHBoxLayout(self.functionInfo)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.label_3 = QLabel(self.centralwidget)
        self.label_3.setObjectName(u"label_3")
        self.label_start = QLabel(self.functionInfo)
        self.label_start.setObjectName(u"label_start")
        self.horizontalLayout.addWidget(self.label_3)
        self.horizontalLayout.addWidget(self.label_start)
        self.functions = QComboBox(self.centralwidget)
        self.functions.addItem("")
        self.functions.addItem("")
        self.functions.addItem("")
        self.functions.addItem("")
        self.functions.setObjectName(u"functions")
        sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.functions.sizePolicy().hasHeightForWidth())
        self.functions.setSizePolicy(sizePolicy)
        self.function = QLineEdit(self.functionInfo)
        self.function.setObjectName(u"function")
        self.horizontalLayout.addWidget(self.functions)
        self.horizontalLayout.addWidget(self.function)
        self.label = QLabel(self.centralwidget)
        self.label.setObjectName(u"label")
        self.label_fn = QLabel(self.functionInfo)
        self.label_fn.setObjectName(u"label_fn")
        self.horizontalLayout.addWidget(self.label)
        self.horizontalLayout.addWidget(self.label_fn)
        self.startValue = QLineEdit(self.centralwidget)
        self.startValue = QLineEdit(self.functionInfo)
        self.startValue.setObjectName(u"startValue")
        self.horizontalLayout.addWidget(self.startValue)
        self.label_2 = QLabel(self.centralwidget)
        self.label_2.setObjectName(u"label_2")
        self.label_end = QLabel(self.functionInfo)
        self.label_end.setObjectName(u"label_end")
        self.horizontalLayout.addWidget(self.label_2)
        self.horizontalLayout.addWidget(self.label_end)
        self.endValue = QLineEdit(self.centralwidget)
        self.endValue = QLineEdit(self.functionInfo)
        self.endValue.setObjectName(u"endValue")
        self.horizontalLayout.addWidget(self.endValue)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.verticalLayout.addWidget(self.functionInfo)
        self.horizontalLayout_2 = QHBoxLayout()
        self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
@@ -81,27 +74,93 @@
        self.horizontalLayout_2.addItem(self.horizontalSpacer)
        self.pushButton = QPushButton(self.centralwidget)
        self.pushButton.setObjectName(u"pushButton")
        self.plotBtn = QPushButton(self.centralwidget)
        self.plotBtn.setObjectName(u"plotBtn")
        self.horizontalLayout_2.addWidget(self.pushButton)
        self.horizontalLayout_2.addWidget(self.plotBtn)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.plainTextEdit = QPlainTextEdit(self.centralwidget)
        self.plainTextEdit.setObjectName(u"plainTextEdit")
        sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.plainTextEdit.sizePolicy().hasHeightForWidth())
        self.plainTextEdit.setSizePolicy(sizePolicy)
        font = QFont()
        font.setFamilies([u"Noto Mono"])
        self.plainTextEdit.setFont(font)
        self.plainTextEdit.setReadOnly(True)
        self.verticalLayout.addWidget(self.plainTextEdit)
        self.verticalLayout_2.addLayout(self.verticalLayout)
        self.groupBox = QGroupBox(self.centralwidget)
        self.groupBox.setObjectName(u"groupBox")
        self.groupBox.setEnabled(True)
        sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Expanding)
        self.breakRule = QGroupBox(self.centralwidget)
        self.breakRule.setObjectName(u"breakRule")
        self.verticalLayout_3 = QVBoxLayout(self.breakRule)
        self.verticalLayout_3.setObjectName(u"verticalLayout_3")
        self.horizontalLayout_5 = QHBoxLayout()
        self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
        self.label_4 = QLabel(self.breakRule)
        self.label_4.setObjectName(u"label_4")
        self.horizontalLayout_5.addWidget(self.label_4)
        self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
        self.horizontalLayout_5.addItem(self.horizontalSpacer_2)
        self.espilon = QLineEdit(self.breakRule)
        self.espilon.setObjectName(u"espilon")
        sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)
        sizePolicy1.setHorizontalStretch(0)
        sizePolicy1.setVerticalStretch(0)
        sizePolicy1.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
        self.groupBox.setSizePolicy(sizePolicy1)
        sizePolicy1.setHeightForWidth(self.espilon.sizePolicy().hasHeightForWidth())
        self.espilon.setSizePolicy(sizePolicy1)
        self.verticalLayout_2.addWidget(self.groupBox)
        self.horizontalLayout_5.addWidget(self.espilon)
        self.verticalLayout_3.addLayout(self.horizontalLayout_5)
        self.horizontalLayout_3 = QHBoxLayout()
        self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
        self.label_5 = QLabel(self.breakRule)
        self.label_5.setObjectName(u"label_5")
        self.horizontalLayout_3.addWidget(self.label_5)
        self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
        self.horizontalLayout_3.addItem(self.horizontalSpacer_3)
        self.section = QLineEdit(self.breakRule)
        self.section.setObjectName(u"section")
        sizePolicy1.setHeightForWidth(self.section.sizePolicy().hasHeightForWidth())
        self.section.setSizePolicy(sizePolicy1)
        self.horizontalLayout_3.addWidget(self.section)
        self.verticalLayout_3.addLayout(self.horizontalLayout_3)
        self.verticalLayout_2.addWidget(self.breakRule)
        self.plotBox = QGroupBox(self.centralwidget)
        self.plotBox.setObjectName(u"plotBox")
        self.plotBox.setEnabled(True)
        sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Expanding)
        sizePolicy2.setHorizontalStretch(0)
        sizePolicy2.setVerticalStretch(0)
        sizePolicy2.setHeightForWidth(self.plotBox.sizePolicy().hasHeightForWidth())
        self.plotBox.setSizePolicy(sizePolicy2)
        self.verticalLayout_2.addWidget(self.plotBox)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
@@ -119,15 +178,23 @@
    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"Riemann Sum", None))
        self.label_3.setText(QCoreApplication.translate("MainWindow", u"Funktion", None))
        self.functions.setItemText(0, QCoreApplication.translate("MainWindow", u"sin", None))
        self.functions.setItemText(1, QCoreApplication.translate("MainWindow", u"cos", None))
        self.functions.setItemText(2, QCoreApplication.translate("MainWindow", u"x^2", None))
        self.functions.setItemText(3, QCoreApplication.translate("MainWindow", u"x^3", None))
        self.label.setText(QCoreApplication.translate("MainWindow", u"start", None))
        self.label_2.setText(QCoreApplication.translate("MainWindow", u"end", None))
        self.pushButton.setText(QCoreApplication.translate("MainWindow", u"Ok", None))
        self.groupBox.setTitle(QCoreApplication.translate("MainWindow", u"Plot", None))
        self.functionInfo.setTitle(QCoreApplication.translate("MainWindow", u"Angabe der Funktion", None))
        self.label_start.setText(QCoreApplication.translate("MainWindow", u"Funktion f(x) = ", None))
        self.function.setText(QCoreApplication.translate("MainWindow", u"x ** 2", None))
        self.label_fn.setText(QCoreApplication.translate("MainWindow", u"start", None))
        self.startValue.setText(QCoreApplication.translate("MainWindow", u"0", None))
        self.label_end.setText(QCoreApplication.translate("MainWindow", u"end", None))
        self.endValue.setText(QCoreApplication.translate("MainWindow", u"4", None))
        self.plotBtn.setText(QCoreApplication.translate("MainWindow", u"Ok", None))
        self.plainTextEdit.setPlainText(QCoreApplication.translate("MainWindow", u"Die Funktion f(x) kann eine belibige Kombination von arithmetischen Operationen und Python mathematische Funktion in Modul math sein. Einige Beispiele sind:\n"
"\n"
"x ** 2\n"
"x ** 3\n"
"tan(radians(x))", None))
        self.breakRule.setTitle(QCoreApplication.translate("MainWindow", u"Abbuchkriterium", None))
        self.label_4.setText(QCoreApplication.translate("MainWindow", u"Maximum Differenz ziwschen Link- und Recht-Summe", None))
        self.label_5.setText(QCoreApplication.translate("MainWindow", u"Anzahl der Sektionen", None))
        self.section.setText(QCoreApplication.translate("MainWindow", u"8", None))
        self.plotBox.setTitle(QCoreApplication.translate("MainWindow", u"Plot", None))
    # retranslateUi
num-int/test/numint/RiemannSum_test.py
File was deleted
num-int/test/numint/riemann_sum_test.py
New file
@@ -0,0 +1,38 @@
import sys
import unittest
from numint.riemann_sum import split, numint_epsilon, numint_compact, numint_section
class RiemannSumTestCase(unittest.TestCase):
    """
    TODO (Aufgabe) Schreiben Sie Kriterien in Unittest
    Die Kriterien sind solche Befehlen mit self.assertXXXX
    """
    def test_split_interval(self):
        split(iteration=6)
    def test_numint_epsilon(self):
        def fn(x) : return x**2
        (a, b) = (0, 2)
        (x, y, l, r, n) = numint_epsilon(fn, a, b)
        print(l, r)  # print Take too much place on screen
        pass
    def test_numint_section(self):
        def fn(x) : return x**2
        (a, b) = (0, 2)
        (x, y, l, r, n) = numint_section(fn, a, b, section_count=8)
        print(l, r)
    def test_numint_compact(self):
        def fn(x) : return x**2
        (a, b) = (0, 2)
        (l, r) = numint_compact(fn, a, b, epsilon=1E9 * sys.float_info.epsilon)
        print(l, r)
        pass
if __name__ == '__main__':
    unittest.main()