From 13963abe51def347a3829174efe64b8dd68b1fbb Mon Sep 17 00:00:00 2001
From: Hong-Phuc Bui <hong-phuc.bui@htwsaar.de>
Date: Fri, 30 May 2025 11:06:44 +0200
Subject: [PATCH] NiceGUI vs Tk 27.5.2025

---
 nicegui-tk-bezier/.gitignore                 |    3 
 .gitignore                                   |   12 ++
 python-typing/python-typing.handout.pdf      |    0 
 python-typing/python-typing.presentation.pdf |    0 
 nicegui-tk-bezier/README.md                  |   24 ++++
 nicegui-tk-bezier/bezier.py                  |   43 ++++++++
 nicegui-tk-bezier/main-nicegui.py            |   28 +++++
 /dev/null                                    |   10 --
 nicegui-tk-bezier/requirements.txt           |    1 
 nicegui-tk-bezier/main-canvas.py             |   36 +++++++
 nicegui-tk-bezier/dummy.txt                  |   52 ++++++++++
 python-typing/py-type-demo/measure.py        |   17 ++
 python-typing/python-typing.tex              |   34 +++++-
 13 files changed, 240 insertions(+), 20 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..813620a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+*.aux
+*.log
+*.snm
+*.out
+*.synctex.gz
+*.toc
+*.vrb
+*.nav
+_minted-*/
+*.idea/
+
+
diff --git a/nicegui-tk-bezier/.gitignore b/nicegui-tk-bezier/.gitignore
new file mode 100644
index 0000000..31dc02d
--- /dev/null
+++ b/nicegui-tk-bezier/.gitignore
@@ -0,0 +1,3 @@
+.venv/
+.idea/
+__pycache__/
\ No newline at end of file
diff --git a/nicegui-tk-bezier/README.md b/nicegui-tk-bezier/README.md
new file mode 100644
index 0000000..8df778b
--- /dev/null
+++ b/nicegui-tk-bezier/README.md
@@ -0,0 +1,24 @@
+# Demo NiceGUI vs Tk
+
+## Install
+
+```bash
+python3.13 -m venv .venv
+source .venv/bin/activate
+pip install -r requirements.txt
+```
+
+
+## Run
+
+### Tk
+
+```bash
+python ./main-canvas.py
+```
+
+### NiceGUI
+
+```bash
+python ./main-nicegui.py
+```
diff --git a/nicegui-tk-bezier/bezier.py b/nicegui-tk-bezier/bezier.py
new file mode 100644
index 0000000..b491a1a
--- /dev/null
+++ b/nicegui-tk-bezier/bezier.py
@@ -0,0 +1,43 @@
+""""
+Module related to bezier curve
+"""
+def make_cubic_bezier(control_points: [(float, float)], n: int = 10) -> [(float, float)]:
+    """"
+    Interpolate a Bezier-curve by split it into segments of lines (=polyline).
+    A Bezier-Curve is defined by
+
+        \[
+            B(P_0, P_1, P_2, P_3:t) = (1-t)^3*P_0 + 3(1-t)^2*t*P_1 + 3(1-t)*t^2*P_2 + t^3*P_3
+        \]
+
+    for $t \in \[0, 1\]$
+
+    :param control_points
+    :param n number of segments
+    :return a list of points on the Bezier-Curve.
+    """
+
+    p0x = control_points[0][0]
+    p0y = control_points[0][1]
+    p1x = control_points[1][0]
+    p1y = control_points[1][1]
+    p2x = control_points[2][0]
+    p2y = control_points[2][1]
+    p3x = control_points[3][0]
+    p3y = control_points[3][1]
+    points = [(p0x, p0y)]
+    for i in range(1, n):
+        t = i / n
+        u = 1 - t
+        x = p0x * u**3 + 3 * p1x * t* u**2 + 3 * p2x * t**2 * u + p3x * t**3
+        y = p0y * u**3 + 3 * p1y * t* u**2 + 3 * p2y * t**2 * u + p3y * t**3
+        points.append( (x,y) )
+    points.append((p3x, p3y))
+    return points
+
+
+def make_svg_polyline(points) -> str:
+    line = map(lambda p: f"{p[0]},{p[1]}", points)
+    svg = f'<polyline points="{" ".join(line)}" fill="none" stroke="gray" stroke-width="3" />'
+    return svg
+
diff --git a/nicegui-tk-bezier/dummy.txt b/nicegui-tk-bezier/dummy.txt
new file mode 100644
index 0000000..08d13e5
--- /dev/null
+++ b/nicegui-tk-bezier/dummy.txt
@@ -0,0 +1,52 @@
+aiofiles==24.1.0
+aiohappyeyeballs==2.6.1
+aiohttp==3.12.4
+aiosignal==1.3.2
+annotated-types==0.7.0
+anyio==4.9.0
+attrs==25.3.0
+bidict==0.23.1
+certifi==2025.4.26
+charset-normalizer==3.4.2
+click==8.2.1
+docutils==0.21.2
+fastapi==0.115.12
+frozenlist==1.6.0
+h11==0.16.0
+httpcore==1.0.9
+httptools==0.6.4
+httpx==0.28.1
+idna==3.10
+ifaddr==0.2.0
+itsdangerous==2.2.0
+Jinja2==3.1.6
+markdown2==2.5.3
+MarkupSafe==3.0.2
+multidict==6.4.4
+nicegui==2.18.0
+orjson==3.10.18
+propcache==0.3.1
+pscript==0.7.7
+pydantic==2.11.5
+pydantic_core==2.33.2
+Pygments==2.19.1
+python-dotenv==1.1.0
+python-engineio==4.12.1
+python-multipart==0.0.20
+python-socketio==5.13.0
+PyYAML==6.0.2
+requests==2.32.3
+simple-websocket==1.1.0
+sniffio==1.3.1
+starlette==0.46.2
+typing-inspection==0.4.1
+typing_extensions==4.13.2
+urllib3==2.4.0
+uvicorn==0.34.2
+uvloop==0.21.0
+vbuild==0.8.2
+wait_for2==0.3.2
+watchfiles==1.0.5
+websockets==15.0.1
+wsproto==1.2.0
+yarl==1.20.0
diff --git a/nicegui-tk-bezier/main-canvas.py b/nicegui-tk-bezier/main-canvas.py
new file mode 100644
index 0000000..756cfa8
--- /dev/null
+++ b/nicegui-tk-bezier/main-canvas.py
@@ -0,0 +1,36 @@
+from tkinter import *
+
+from bezier import make_cubic_bezier
+
+def draw_bezier(canvas, control_points):
+    points = make_cubic_bezier(control_points, n= 400)
+    for i in range(1,len(points)):
+        x1 = points[i-1][0]
+        y1 = points[i-1][1]
+        x2 = points[i][0]
+        y2 = points[i][1]
+        canvas.create_line(x1,y1, x2,y2)
+
+
+def get_point(event):
+    global control_points
+    point = x, y = (event.x, event.y)
+    control_points.append(point)
+    canvas.create_oval(x, y, x+3, y+3)
+    if len(control_points) == 4:
+        draw_bezier(canvas, control_points)
+        control_points = []
+
+
+if __name__ == '__main__':
+
+    control_points = []
+
+    root = Tk()
+
+    canvas = Canvas(root, width=800, height=800)
+    canvas.pack()
+
+    canvas.bind('<Button-1>', get_point)
+
+    root.mainloop()
\ No newline at end of file
diff --git a/nicegui-tk-bezier/main-nicegui.py b/nicegui-tk-bezier/main-nicegui.py
new file mode 100644
index 0000000..4a055ea
--- /dev/null
+++ b/nicegui-tk-bezier/main-nicegui.py
@@ -0,0 +1,28 @@
+from nicegui import ui
+
+from bezier import make_cubic_bezier, make_svg_polyline
+
+control_points = []
+svg = ""
+
+def get_point(event):
+    global control_points
+    global svg
+    x = event.image_x
+    y = event.image_y
+    control_points.append((x,y))
+    svg += f'<circle cx="{x}" cy="{y}" r="1" fill="orange" />'
+    ui.notification(f"(x,y) = ({x},{y})")
+    if len(control_points) == 4:
+        bezier_points = make_cubic_bezier(control_points, n = 50)
+        svg += make_svg_polyline(bezier_points)
+        control_points.clear()
+    event.sender.set_content(svg)
+
+ui.interactive_image(
+    size=(900, 400), cross=True,
+    on_mouse=get_point,
+).classes('w-full bg-blue-50')
+
+ui.run()
+
diff --git a/nicegui-tk-bezier/requirements.txt b/nicegui-tk-bezier/requirements.txt
new file mode 100644
index 0000000..e57426a
--- /dev/null
+++ b/nicegui-tk-bezier/requirements.txt
@@ -0,0 +1 @@
+nicegui==2.18.0
diff --git a/python-typing/py-type-demo/.idea/.gitignore b/python-typing/py-type-demo/.idea/.gitignore
deleted file mode 100644
index 26d3352..0000000
--- a/python-typing/py-type-demo/.idea/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
diff --git a/python-typing/py-type-demo/.idea/inspectionProfiles/profiles_settings.xml b/python-typing/py-type-demo/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 105ce2d..0000000
--- a/python-typing/py-type-demo/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <settings>
-    <option name="USE_PROJECT_PROFILE" value="false" />
-    <version value="1.0" />
-  </settings>
-</component>
\ No newline at end of file
diff --git a/python-typing/py-type-demo/.idea/misc.xml b/python-typing/py-type-demo/.idea/misc.xml
deleted file mode 100644
index 5f683b8..0000000
--- a/python-typing/py-type-demo/.idea/misc.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Black">
-    <option name="sdkName" value="Python 3.12 (py-type-demo)" />
-  </component>
-  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (py-type-demo)" project-jdk-type="Python SDK" />
-</project>
\ No newline at end of file
diff --git a/python-typing/py-type-demo/.idea/modules.xml b/python-typing/py-type-demo/.idea/modules.xml
deleted file mode 100644
index 0a4f4ae..0000000
--- a/python-typing/py-type-demo/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/.idea/py-type-demo.iml" filepath="$PROJECT_DIR$/.idea/py-type-demo.iml" />
-    </modules>
-  </component>
-</project>
\ No newline at end of file
diff --git a/python-typing/py-type-demo/.idea/py-type-demo.iml b/python-typing/py-type-demo/.idea/py-type-demo.iml
deleted file mode 100644
index 2c80e12..0000000
--- a/python-typing/py-type-demo/.idea/py-type-demo.iml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="PYTHON_MODULE" version="4">
-  <component name="NewModuleRootManager">
-    <content url="file://$MODULE_DIR$">
-      <excludeFolder url="file://$MODULE_DIR$/.venv" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/python-typing/py-type-demo/measure.py b/python-typing/py-type-demo/measure.py
index 2da05d4..fb2180c 100644
--- a/python-typing/py-type-demo/measure.py
+++ b/python-typing/py-type-demo/measure.py
@@ -1,12 +1,20 @@
-from typing import Sequence, Callable, TypeAlias
-
-measurement: Sequence[int | float] = [12.5, 11, 12.3, 11.6, 11.1, 12]
-
+from typing import Sequence, Callable, TypeAlias, Iterable
 
 def avg(values: Sequence[int | float]) -> float:
     return sum(values) / len(values)
 
+length: list[int | float] = [12.5, 11, 12.3, 11.6, 11.1, 12]
+length_avg = avg(length)
 
+
+count_member: tuple[int, int, int, int, int] = (12, 15, 16, 11, 10)
+member_avg = avg(count_member)
+print(member_avg)
+
+prime_set: set[int] = {2, 3, 5, 7, 11}  #
+prime_avg = avg(prime_set)
+
+"""
 avg: Callable[[Sequence[int | float]], float] = \
     lambda values: sum(values) / len(values)
 
@@ -15,3 +23,4 @@
 avg: Callable[[Scale], float] = \
     lambda v: sum(v) / len(v) if len(v) > 0 else 0.0
 
+"""
\ No newline at end of file
diff --git a/python-typing/python-typing.handout.pdf b/python-typing/python-typing.handout.pdf
index 49ae66c..67a99a3 100644
--- a/python-typing/python-typing.handout.pdf
+++ b/python-typing/python-typing.handout.pdf
Binary files differ
diff --git a/python-typing/python-typing.presentation.pdf b/python-typing/python-typing.presentation.pdf
index 60f835b..bae2c02 100644
--- a/python-typing/python-typing.presentation.pdf
+++ b/python-typing/python-typing.presentation.pdf
Binary files differ
diff --git a/python-typing/python-typing.tex b/python-typing/python-typing.tex
index 52fc9e2..8043724 100644
--- a/python-typing/python-typing.tex
+++ b/python-typing/python-typing.tex
@@ -124,14 +124,11 @@
 \end{minted}
 \end{frame}
 
-\subsection{Union}
+\subsection{Union und Generic}
 \begin{frame}[fragile]
 \frametitle{Union}
 \begin{minted}{python}
-from typing import Sequence
-
-
-measurement: Sequence[int | float] = [12.5, 11, 12.3, 11.6, 11.1, 12]
+measurement: list[int | float] = [12.5, 11, 12.3, 11.6, 11.1, 12]
 \end{minted}
 \pause
 
@@ -140,7 +137,7 @@
 
 
 \begin{frame}[fragile]
-\frametitle{Funktionsparameter}
+\frametitle{Generic}
 
 \begin{minted}{python}
 def avg(values: Sequence[int | float]) -> float:
@@ -156,6 +153,31 @@
 \end{minted}
 \end{frame}
 
+\begin{frame}[fragile]
+\frametitle{Aufruf}
+\begin{minted}{python}
+# List Ok
+length: list[int | float] = [12.5, 11, 12.3, 11.6, 11.1, 12]
+length_avg = avg(length)
+
+# Tupel Ok
+count_member: tuple[int, int, int, int, int] = (12, 15, 16, 11, 10)
+member_avg = avg(count_member)
+\end{minted}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{Pitfall}
+\begin{minted}{python}
+# Set is not a Sequence
+my_set: set[int] = {2, 3, 5, 7, 11}  # 
+prime_avg = avg(prime_set)
+
+
+# mypy:
+# ...incompatible type "Set[int]"; expected "Sequence[Union[int, float]]"
+\end{minted}
+\end{frame}
 
 \subsection{TypeAlias}
 \begin{frame}[fragile]

--
Gitblit v1.10.0-SNAPSHOT