From 8a9933e4decb3b6a57b47b6409474bd476920c24 Mon Sep 17 00:00:00 2001
From: Hong-Phuc Bui <hong-phuc.bui@htwsaar.de>
Date: Fri, 27 Sep 2024 01:22:49 +0200
Subject: [PATCH] demo show image
---
/dev/null | 251 -------------------
image-demo/README.md | 20 +
image-demo/src/imgdemo/ui_mainwindow.py | 111 ++++++++
stundenplan/src/pygraph/graphdemo.py | 18
stundenplan/src/pygraph/shortestpath.py | 53 ++++
image-demo/src/imgdemo/__init__.py | 0
image-demo/pyproject.toml | 19 +
stundenplan/tests/pygraph/shortestpath_tests.py | 53 +++
bit_op_numpy_example.py | 41 +++
image-demo/src/imgdemo/guimain.py | 74 +++++
image-demo/src/imgdemo/mainwindow.ui | 107 ++++++++
11 files changed, 475 insertions(+), 272 deletions(-)
diff --git a/bit_op_numpy_example.py b/bit_op_numpy_example.py
new file mode 100644
index 0000000..c80d8bb
--- /dev/null
+++ b/bit_op_numpy_example.py
@@ -0,0 +1,41 @@
+import numpy as np
+
+def print_binary_pattern_32(x):
+ pattern = bin(x)[2:].zfill(32)
+ print(x, ':', pattern[0:8], pattern[9:16], pattern[17:24], pattern[25:], len(pattern))
+
+def to32_np_fn(x: list[np.uint8,np.uint8,np.uint8,np.uint8]):
+ y = np.left_shift(x, [np.uint32(0), np.uint32(8), np.uint32(16), np.uint32(24)])
+ return y[0] | y[1] | y[2] | y[3]
+
+
+def to32_bit_op(x: list[np.uint8,np.uint8,np.uint8,np.uint8]):
+ # 1 0000_0000 0000_0000 0000_0000 0000_0000
+ mask = (2**32) | (x[3] << 24) | (x[2] << 16) | (x[1] << 8) | (x[0])
+ # remove the most significant bit
+ return mask & (2**32-1)
+
+
+def quaternary_8bit_to_unary_32bit(data, to32_fn):
+ four_group = np.array(data, dtype=np.uint8).reshape((-1, 4))
+ return np.array([to32_fn(x) for x in four_group])
+
+
+
+if __name__ == '__main__':
+ raw_data = [255, 0, 15, 170,
+ 0b101, 0b1100, 0b1001101, 0b1000_0000,
+ 9, 10, 11, 0b1000_0000]
+
+ print(f"Konvertierung jeweiliger 4er-Tuple in einem uint32")
+ print()
+ print("Mit Python built-int Left-Shift-Operator")
+ result = quaternary_8bit_to_unary_32bit(raw_data, to32_np_fn)
+ for r in result:
+ print_binary_pattern_32(r)
+
+ print()
+ print("Mit numpy left_shift Funktion")
+ result = quaternary_8bit_to_unary_32bit(raw_data, to32_bit_op)
+ for r in result:
+ print_binary_pattern_32(r)
\ No newline at end of file
diff --git a/image-demo/README.md b/image-demo/README.md
new file mode 100644
index 0000000..da86bd4
--- /dev/null
+++ b/image-demo/README.md
@@ -0,0 +1,20 @@
+# Demonstration von Zusammenspiel numpy/PIL und PySide6
+
+## Build python file from ui
+
+```shell
+pyside6-project build imgdemo.json
+```
+
+## Install as development mode (editable)
+
+```
+pip install -e .
+```
+
+## Run the application after install
+
+
+```
+imgdemo
+```
\ No newline at end of file
diff --git a/image-demo/pyproject.toml b/image-demo/pyproject.toml
new file mode 100644
index 0000000..4f2fb7d
--- /dev/null
+++ b/image-demo/pyproject.toml
@@ -0,0 +1,19 @@
+[build-system]
+requires = ["setuptools"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "image-demo"
+version = "0.0.1"
+dependencies = [
+ "numpy >= 2.0.0",
+ "matplotlib >= 3.9",
+ "PySide6 >= 6.7"
+]
+
+[tool.setuptools.packages.find]
+# All the following settings are optional:
+where = ["src"]
+
+[project.gui-scripts]
+imgdemo = "imgdemo.guimain:main"
diff --git a/image-demo/src/imgdemo/__init__.py b/image-demo/src/imgdemo/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/image-demo/src/imgdemo/__init__.py
diff --git a/image-demo/src/imgdemo/guimain.py b/image-demo/src/imgdemo/guimain.py
new file mode 100644
index 0000000..665f312
--- /dev/null
+++ b/image-demo/src/imgdemo/guimain.py
@@ -0,0 +1,74 @@
+import sys
+
+from PySide6.QtGui import QPixmap, QImage
+#from PIL.ImageQt import QPixmap, QImage
+
+from PySide6.QtWidgets import QApplication, QMainWindow, QFileDialog
+import numpy as np
+from PIL import Image
+
+from imgdemo.ui_mainwindow import Ui_MainWindow
+
+class MainWindow(QMainWindow):
+ def __init__(self):
+ super(MainWindow, self).__init__()
+ self.saved_file = ('', '')
+ self.chosen_file = ('', '')
+ self.ui = Ui_MainWindow()
+ self.ui.setupUi(self)
+ self.ui.actionChoose_Image.triggered.connect(self.choose_image)
+ self.ui.actionSave_Image.triggered.connect(self.save_image)
+
+ def choose_image(self):
+ self.chosen_file = ('', '') # reset (for safe)
+ self.chosen_file = QFileDialog.getOpenFileName(None, "Choose Image", "",
+ "Images (*.png *.xpm *.jpg *.tiff) ;; All Filetypes (*.*)")
+ print(self.chosen_file)
+ if self.chosen_file[0] != '': # user has chosen a file
+ self.display_image()
+
+
+ def save_image(self):
+ self.saved_file = ('', '') # reset for safe
+ self.saved_file = QFileDialog.getSaveFileName(None, "Choose Image", "",
+ "All (*.*)")
+ print(self.saved_file)
+
+
+ def display_image(self):
+ pixmap = QPixmap(self.chosen_file[0])
+ self.ui.origin_img.setPixmap(pixmap)
+ # now read the image and show it via Image in other container
+ with Image.open(self.chosen_file[0]) as img:
+ image = np.asarray(img, dtype=np.uint8)
+ self.display_numpy_image(image)
+
+
+ def display_numpy_image(self, image):
+ height, width, channel = image.shape
+ print(height, width, channel)
+
+ bytes_per_line = channel * width # color
+ img_format = QImage.Format.Format_RGBX8888
+ if channel == 4:
+ img_format = QImage.Format.Format_ARGB32
+ elif channel == 3:
+ img_format = QImage.Format.Format_RGB888
+ qImg = QImage(image.data, width, height, bytes_per_line, img_format).rgbSwapped()
+ pixmap = QPixmap(qImg)
+ self.ui.result_img.setPixmap(pixmap)
+
+
+
+
+def main():
+ app = QApplication(sys.argv)
+ window = MainWindow()
+ window.show()
+
+ sys.exit(app.exec())
+ pass
+
+
+if __name__ == "__main__":
+ main()
diff --git a/image-demo/src/imgdemo/mainwindow.ui b/image-demo/src/imgdemo/mainwindow.ui
new file mode 100644
index 0000000..f0db623
--- /dev/null
+++ b/image-demo/src/imgdemo/mainwindow.ui
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>600</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Image Demo</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QGroupBox" name="origin_container">
+ <property name="title">
+ <string>Origin Image</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="origin_img">
+ <property name="text">
+ <string>Source</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="result_container">
+ <property name="title">
+ <string>Filtered Image</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="result_img">
+ <property name="text">
+ <string>Result</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButton">
+ <property name="text">
+ <string>Dummy Widget</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>800</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuFile">
+ <property name="title">
+ <string>&File</string>
+ </property>
+ <addaction name="actionChoose_Image"/>
+ <addaction name="actionSave_Image"/>
+ </widget>
+ <addaction name="menuFile"/>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ <action name="actionChoose_Image">
+ <property name="icon">
+ <iconset theme="QIcon::ThemeIcon::FolderOpen"/>
+ </property>
+ <property name="text">
+ <string>Choose Image</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="actionSave_Image">
+ <property name="icon">
+ <iconset theme="QIcon::ThemeIcon::DocumentSave"/>
+ </property>
+ <property name="text">
+ <string>Save Image</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+S</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/image-demo/src/imgdemo/ui_mainwindow.py b/image-demo/src/imgdemo/ui_mainwindow.py
new file mode 100644
index 0000000..6a997bd
--- /dev/null
+++ b/image-demo/src/imgdemo/ui_mainwindow.py
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'mainwindow.ui'
+##
+## Created by: Qt User Interface Compiler version 6.7.2
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
+ QMetaObject, QObject, QPoint, QRect,
+ QSize, QTime, QUrl, Qt)
+from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
+ QCursor, QFont, QFontDatabase, QGradient,
+ QIcon, QImage, QKeySequence, QLinearGradient,
+ QPainter, QPalette, QPixmap, QRadialGradient,
+ QTransform)
+from PySide6.QtWidgets import (QApplication, QGroupBox, QHBoxLayout, QLabel,
+ QMainWindow, QMenu, QMenuBar, QPushButton,
+ QSizePolicy, QStatusBar, QVBoxLayout, QWidget)
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ if not MainWindow.objectName():
+ MainWindow.setObjectName(u"MainWindow")
+ MainWindow.resize(800, 600)
+ self.actionChoose_Image = QAction(MainWindow)
+ self.actionChoose_Image.setObjectName(u"actionChoose_Image")
+ icon = QIcon(QIcon.fromTheme(QIcon.ThemeIcon.FolderOpen))
+ self.actionChoose_Image.setIcon(icon)
+ self.actionSave_Image = QAction(MainWindow)
+ self.actionSave_Image.setObjectName(u"actionSave_Image")
+ icon1 = QIcon(QIcon.fromTheme(QIcon.ThemeIcon.DocumentSave))
+ self.actionSave_Image.setIcon(icon1)
+ self.centralwidget = QWidget(MainWindow)
+ self.centralwidget.setObjectName(u"centralwidget")
+ self.verticalLayout_3 = QVBoxLayout(self.centralwidget)
+ self.verticalLayout_3.setObjectName(u"verticalLayout_3")
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.origin_container = QGroupBox(self.centralwidget)
+ self.origin_container.setObjectName(u"origin_container")
+ self.verticalLayout_2 = QVBoxLayout(self.origin_container)
+ self.verticalLayout_2.setObjectName(u"verticalLayout_2")
+ self.origin_img = QLabel(self.origin_container)
+ self.origin_img.setObjectName(u"origin_img")
+
+ self.verticalLayout_2.addWidget(self.origin_img)
+
+
+ self.horizontalLayout.addWidget(self.origin_container)
+
+ self.result_container = QGroupBox(self.centralwidget)
+ self.result_container.setObjectName(u"result_container")
+ self.verticalLayout = QVBoxLayout(self.result_container)
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.result_img = QLabel(self.result_container)
+ self.result_img.setObjectName(u"result_img")
+
+ self.verticalLayout.addWidget(self.result_img)
+
+
+ self.horizontalLayout.addWidget(self.result_container)
+
+
+ self.verticalLayout_3.addLayout(self.horizontalLayout)
+
+ self.pushButton = QPushButton(self.centralwidget)
+ self.pushButton.setObjectName(u"pushButton")
+
+ self.verticalLayout_3.addWidget(self.pushButton)
+
+ MainWindow.setCentralWidget(self.centralwidget)
+ self.menubar = QMenuBar(MainWindow)
+ self.menubar.setObjectName(u"menubar")
+ self.menubar.setGeometry(QRect(0, 0, 800, 22))
+ self.menuFile = QMenu(self.menubar)
+ self.menuFile.setObjectName(u"menuFile")
+ MainWindow.setMenuBar(self.menubar)
+ self.statusbar = QStatusBar(MainWindow)
+ self.statusbar.setObjectName(u"statusbar")
+ MainWindow.setStatusBar(self.statusbar)
+
+ self.menubar.addAction(self.menuFile.menuAction())
+ self.menuFile.addAction(self.actionChoose_Image)
+ self.menuFile.addAction(self.actionSave_Image)
+
+ self.retranslateUi(MainWindow)
+
+ QMetaObject.connectSlotsByName(MainWindow)
+ # setupUi
+
+ def retranslateUi(self, MainWindow):
+ MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"Image Demo", None))
+ self.actionChoose_Image.setText(QCoreApplication.translate("MainWindow", u"Choose Image", None))
+#if QT_CONFIG(shortcut)
+ self.actionChoose_Image.setShortcut(QCoreApplication.translate("MainWindow", u"Ctrl+O", None))
+#endif // QT_CONFIG(shortcut)
+ self.actionSave_Image.setText(QCoreApplication.translate("MainWindow", u"Save Image", None))
+#if QT_CONFIG(shortcut)
+ self.actionSave_Image.setShortcut(QCoreApplication.translate("MainWindow", u"Ctrl+S", None))
+#endif // QT_CONFIG(shortcut)
+ self.origin_container.setTitle(QCoreApplication.translate("MainWindow", u"Origin Image", None))
+ self.origin_img.setText(QCoreApplication.translate("MainWindow", u"Source", None))
+ self.result_container.setTitle(QCoreApplication.translate("MainWindow", u"Filtered Image", None))
+ self.result_img.setText(QCoreApplication.translate("MainWindow", u"Result", None))
+ self.pushButton.setText(QCoreApplication.translate("MainWindow", u"Dummy Widget", None))
+ self.menuFile.setTitle(QCoreApplication.translate("MainWindow", u"&File", None))
+ # retranslateUi
+
diff --git a/num-int/src/numint/ui_mainwindow.py b/num-int/src/numint/ui_mainwindow.py
deleted file mode 100644
index 84d39bb..0000000
--- a/num-int/src/numint/ui_mainwindow.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# -*- coding: utf-8 -*-
-
-################################################################################
-## Form generated from reading UI file 'mainwindow.ui'
-##
-## Created by: Qt User Interface Compiler version 6.7.2
-##
-## WARNING! All changes made in this file will be lost when recompiling UI file!
-################################################################################
-
-from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
- QMetaObject, QObject, QPoint, QRect,
- QSize, QTime, QUrl, Qt)
-from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
- QFont, QFontDatabase, QGradient, QIcon,
- QImage, QKeySequence, QLinearGradient, QPainter,
- QPalette, QPixmap, QRadialGradient, QTransform)
-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):
- if not MainWindow.objectName():
- MainWindow.setObjectName(u"MainWindow")
- MainWindow.resize(1411, 889)
- self.centralwidget = QWidget(MainWindow)
- self.centralwidget.setObjectName(u"centralwidget")
- self.horizontalLayout_2 = QHBoxLayout(self.centralwidget)
- self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
- self.verticalLayout = QVBoxLayout()
- self.verticalLayout.setObjectName(u"verticalLayout")
- self.helpingText = QPlainTextEdit(self.centralwidget)
- self.helpingText.setObjectName(u"helpingText")
- sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.helpingText.sizePolicy().hasHeightForWidth())
- self.helpingText.setSizePolicy(sizePolicy)
- font = QFont()
- font.setFamilies([u"Noto Mono"])
- self.helpingText.setFont(font)
- self.helpingText.setReadOnly(True)
-
- self.verticalLayout.addWidget(self.helpingText)
-
- self.functionInfo = QGroupBox(self.centralwidget)
- self.functionInfo.setObjectName(u"functionInfo")
- self.formLayout_3 = QFormLayout(self.functionInfo)
- self.formLayout_3.setObjectName(u"formLayout_3")
- self.label_start = QLabel(self.functionInfo)
- self.label_start.setObjectName(u"label_start")
-
- self.formLayout_3.setWidget(0, QFormLayout.LabelRole, self.label_start)
-
- self.function = QLineEdit(self.functionInfo)
- self.function.setObjectName(u"function")
-
- self.formLayout_3.setWidget(0, QFormLayout.FieldRole, self.function)
-
- self.label_fn = QLabel(self.functionInfo)
- self.label_fn.setObjectName(u"label_fn")
-
- self.formLayout_3.setWidget(1, QFormLayout.LabelRole, self.label_fn)
-
- self.startValue = QLineEdit(self.functionInfo)
- self.startValue.setObjectName(u"startValue")
-
- self.formLayout_3.setWidget(1, QFormLayout.FieldRole, self.startValue)
-
- self.label_end = QLabel(self.functionInfo)
- self.label_end.setObjectName(u"label_end")
-
- self.formLayout_3.setWidget(2, QFormLayout.LabelRole, self.label_end)
-
- self.endValue = QLineEdit(self.functionInfo)
- self.endValue.setObjectName(u"endValue")
-
- self.formLayout_3.setWidget(2, QFormLayout.FieldRole, self.endValue)
-
-
- self.verticalLayout.addWidget(self.functionInfo)
-
- self.breakRule = QGroupBox(self.centralwidget)
- self.breakRule.setObjectName(u"breakRule")
- self.formLayout_2 = QFormLayout(self.breakRule)
- self.formLayout_2.setObjectName(u"formLayout_2")
- self.label_4 = QLabel(self.breakRule)
- self.label_4.setObjectName(u"label_4")
-
- self.formLayout_2.setWidget(2, QFormLayout.LabelRole, self.label_4)
-
- 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.espilon.sizePolicy().hasHeightForWidth())
- self.espilon.setSizePolicy(sizePolicy1)
-
- 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(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(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)
-
- self.plotBtn = QPushButton(self.centralwidget)
- self.plotBtn.setObjectName(u"plotBtn")
-
- self.verticalLayout.addWidget(self.plotBtn)
-
- self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
-
- self.verticalLayout.addItem(self.verticalSpacer)
-
- self.riemannSumGruppe = QGroupBox(self.centralwidget)
- self.riemannSumGruppe.setObjectName(u"riemannSumGruppe")
- self.formLayout = QFormLayout(self.riemannSumGruppe)
- self.formLayout.setObjectName(u"formLayout")
- self.label = QLabel(self.riemannSumGruppe)
- self.label.setObjectName(u"label")
-
- self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label)
-
- self.leftSum = QLineEdit(self.riemannSumGruppe)
- self.leftSum.setObjectName(u"leftSum")
- sizePolicy1.setHeightForWidth(self.leftSum.sizePolicy().hasHeightForWidth())
- self.leftSum.setSizePolicy(sizePolicy1)
- self.leftSum.setReadOnly(True)
-
- self.formLayout.setWidget(0, QFormLayout.FieldRole, self.leftSum)
-
- self.label_2 = QLabel(self.riemannSumGruppe)
- self.label_2.setObjectName(u"label_2")
-
- self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_2)
-
- self.rightSum = QLineEdit(self.riemannSumGruppe)
- self.rightSum.setObjectName(u"rightSum")
- sizePolicy1.setHeightForWidth(self.rightSum.sizePolicy().hasHeightForWidth())
- self.rightSum.setSizePolicy(sizePolicy1)
- self.rightSum.setReadOnly(True)
-
- self.formLayout.setWidget(1, QFormLayout.FieldRole, self.rightSum)
-
- self.label_3 = QLabel(self.riemannSumGruppe)
- self.label_3.setObjectName(u"label_3")
-
- self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label_3)
-
- self.numOfSections = QLineEdit(self.riemannSumGruppe)
- self.numOfSections.setObjectName(u"numOfSections")
-
- self.formLayout.setWidget(2, QFormLayout.FieldRole, self.numOfSections)
-
-
- self.verticalLayout.addWidget(self.riemannSumGruppe)
-
-
- self.horizontalLayout_2.addLayout(self.verticalLayout)
-
- self.plotBox = QGroupBox(self.centralwidget)
- self.plotBox.setObjectName(u"plotBox")
- self.plotBox.setEnabled(True)
- sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
- sizePolicy2.setHorizontalStretch(0)
- sizePolicy2.setVerticalStretch(0)
- sizePolicy2.setHeightForWidth(self.plotBox.sizePolicy().hasHeightForWidth())
- self.plotBox.setSizePolicy(sizePolicy2)
-
- self.horizontalLayout_2.addWidget(self.plotBox)
-
- MainWindow.setCentralWidget(self.centralwidget)
- self.menubar = QMenuBar(MainWindow)
- self.menubar.setObjectName(u"menubar")
- self.menubar.setGeometry(QRect(0, 0, 1411, 22))
- MainWindow.setMenuBar(self.menubar)
- self.statusbar = QStatusBar(MainWindow)
- self.statusbar.setObjectName(u"statusbar")
- MainWindow.setStatusBar(self.statusbar)
-
- self.retranslateUi(MainWindow)
-
- QMetaObject.connectSlotsByName(MainWindow)
- # setupUi
-
- def retranslateUi(self, MainWindow):
- MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"Riemann Sum", None))
- self.helpingText.setPlainText(QCoreApplication.translate("MainWindow", u"Die Funktion f(x) kann eine beliebige Kombination von arithmetischen Operationen und Python mathematische Funktion in Modul math sein. Einige Beispiele sind:\n"
-"\n"
-"x ** 2 0 4\n"
-"x ** 3 0 4\n"
-"tan(radians(x)) 0 45\n"
-"sin(x)**3 + cos(x)**3 0 2*pi\n"
-"", 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.breakRule.setTitle(QCoreApplication.translate("MainWindow", u"Abbuchkriterium", None))
- 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))
- self.label_2.setText(QCoreApplication.translate("MainWindow", u"rechte Summe", None))
- self.label_3.setText(QCoreApplication.translate("MainWindow", u"Anzahl der Iterationen", None))
- self.plotBox.setTitle(QCoreApplication.translate("MainWindow", u"Plot", None))
- # retranslateUi
-
diff --git a/stundenplan/src/pygraph/graphdemo.py b/stundenplan/src/pygraph/graphdemo.py
index 2a6cf7d..d8669be 100644
--- a/stundenplan/src/pygraph/graphdemo.py
+++ b/stundenplan/src/pygraph/graphdemo.py
@@ -2,6 +2,9 @@
class Graph:
+ """
+ represents an undirected and unweighted Graph
+ """
def __init__(self):
self._adjacent: dict[int, set] = {}
self._vertex_attribute: dict[int, dict] = {}
@@ -25,7 +28,7 @@
u_neighbor.add(v)
pass
- def add_edges(self, u: int, adjacent:[int]):
+ def add_edges(self, u: int, adjacent: list[int]):
for v in adjacent:
self.add_edge(u, v)
pass
@@ -44,7 +47,7 @@
"""
if vertex not in self._adjacent:
raise ValueError(f"Graph does not include vertex {vertex}")
- old_attributes = self._vertex_attribute.get(vertex)
+ old_attributes = self._vertex_attribute[vertex]
self._vertex_attribute[vertex] = old_attributes | properties
return self
pass
@@ -75,7 +78,7 @@
def adjacent_of(self, vertex: int):
if vertex not in self._adjacent:
raise ValueError(f"Graph does not include vertex {vertex}")
- return sorted( self._adjacent.get(vertex) )
+ return sorted( self._adjacent[vertex] )
def for_each_edges(self, action: Callable[[int, int], Any]):
"""
@@ -87,21 +90,18 @@
for end in self.adjacent_of(start):
(first, second) = (start, end) if (start >= end) else (end, start)
if first in visited_edges:
- visited_adjacent = visited_edges.get(first)
+ #visited_adjacent = visited_edges.get(first)
+ visited_adjacent = visited_edges[first]
if second not in visited_adjacent:
visited_adjacent.add(second)
action(start, end)
else:
- adjacent = set()
+ adjacent: set[int] = set()
visited_edges[first] = adjacent
adjacent.add(second)
action(start, end)
- def get_lecture_name(self, vertex: int):
- pass
- def set_lecture_name(self, vertex: int, name: str):
- pass
def __repr__(self):
text = ""
diff --git a/stundenplan/src/pygraph/shortestpath.py b/stundenplan/src/pygraph/shortestpath.py
index 4426f95..5d3e2af 100644
--- a/stundenplan/src/pygraph/shortestpath.py
+++ b/stundenplan/src/pygraph/shortestpath.py
@@ -1,9 +1,10 @@
import collections
+from typing import Mapping
from pygraph.graphdemo import Graph
-def bfs(g: Graph, start: int) -> {int:int|None}:
+def bfs(g: Graph, start: int) -> Graph:
"""
:param g:
@@ -26,3 +27,53 @@
g.merge_attribute(v, visited)
queue.append(v)
return tree
+
+
+def bfs_dict(g: Graph, start: int) -> Mapping[int, int|None]:
+ tree = {start:None}
+ queue = collections.deque()
+ VISITED = "visited"
+ not_visited = {VISITED: False}
+ visited = {VISITED: True}
+ g.for_each_vertices(lambda v : g.merge_attribute(v, not_visited))
+ queue.append(start) # append() is the enqueue() operation of a Queue
+ g.merge_attribute(start, visited)
+ while queue:
+ u = queue.popleft() # popleft() is the dequeue() operation of a Queue
+ for v in g.adjacent_of(u):
+ if not g.get_attribute(v)[VISITED]:
+ tree[v] = u
+ g.merge_attribute(v, visited)
+ queue.append(v)
+ return tree
+ pass
+
+
+def find_path(g: Graph, u: int, v: int) -> list[int]:
+ tree = bfs_dict(g, v)
+ path = [u]
+ while (current := path[-1]) != v:
+ precedent = tree[current]
+ path.append(precedent)
+ return path
+
+
+def find_path_gpt(g: Graph, u: int, v: int) -> list[int]:
+ # Erstelle einen BFS-Baum, beginnend bei Knoten v
+ bfs_tree = bfs_dict(g, v)
+
+ # Wenn u nicht in bfs_tree ist, gibt es keinen Pfad von u nach v
+ if u not in bfs_tree:
+ return [] # Kein Pfad gefunden
+
+ # Den Pfad von u nach v rekonstruieren
+ path = []
+ current = u
+ while current is not None:
+ path.append(current)
+ current = bfs_tree[current]
+
+ # Den Pfad umkehren, da wir rückwärts von u nach v gehen
+ path.reverse()
+
+ return path
\ No newline at end of file
diff --git a/stundenplan/tests/pygraph/shortestpath_tests.py b/stundenplan/tests/pygraph/shortestpath_tests.py
index 6b9b2de..dc914a1 100644
--- a/stundenplan/tests/pygraph/shortestpath_tests.py
+++ b/stundenplan/tests/pygraph/shortestpath_tests.py
@@ -1,26 +1,57 @@
import unittest
from pygraph.graphdemo import Graph
-from pygraph.shortestpath import bfs
+from pygraph.shortestpath import bfs, bfs_dict, find_path, find_path_gpt
class ShortestPathTestCase(unittest.TestCase):
def test_bfs(self):
g = Graph()
g.add_edges(0, [1, 2])
- g.add_edges(1, [0, 3, 4])
- g.add_edges(2, [0, 4, 6, 7])
- g.add_edges(3, [1])
- g.add_edges(4, [1, 2, 5])
- g.add_edges(5, [4])
- g.add_edges(6, [2])
- g.add_edges(7, [2])
- #print(g)
- # self.assertEqual(True, False) # add assertion here
-
+ g.add_edges(1, [3, 4])
+ g.add_edges(2, [4, 6, 7])
+ g.add_edges(4, [5])
+ print(g)
+ print("#")
tree = bfs(g, 0)
print(tree)
+ def test_bfs_dict(self):
+ g = Graph()
+ g.add_edges(0, [1, 2])
+ g.add_edges(1, [3, 4])
+ g.add_edges(2, [4, 6, 7])
+ g.add_edges(4, [5])
+ print(g)
+ tree = bfs_dict(g, 6)
+ print("Tree from Vertex 6")
+ print(tree)
+
+ def test_find_path(self):
+ g = Graph()
+ g.add_edges(0, [1, 2])
+ g.add_edges(1, [3, 4])
+ g.add_edges(2, [4, 6, 7])
+ g.add_edges(4, [5])
+ print(g)
+ (u, v) = (6, 5)
+ path = find_path(g, 6, 5)
+ print(f"path from {u} to {v}")
+ print(path)
+
+ def test_find_path_gpt(self):
+ g = Graph()
+ g.add_edges(0, [1, 2])
+ g.add_edges(1, [3, 4])
+ g.add_edges(2, [4, 6, 7])
+ g.add_edges(4, [5])
+ print(g)
+ (u, v) = (6, 5)
+ path = find_path_gpt(g, 6, 5)
+ print(f"path from {u} to {v}")
+ print(path)
+
+
if __name__ == '__main__':
unittest.main()
--
Gitblit v1.10.0