4 files modified
8 files added
5 files deleted
New file |
| | |
| | | *.aux |
| | | *.log |
| | | *.snm |
| | | *.out |
| | | *.synctex.gz |
| | | *.toc |
| | | *.vrb |
| | | *.nav |
| | | _minted-*/ |
| | | *.idea/ |
| | | |
| | | |
New file |
| | |
| | | .venv/ |
| | | .idea/ |
| | | __pycache__/ |
New file |
| | |
| | | # Demo NiceGUI vs Tk |
| | | |
| | | Eine kleine Demonstration von Plot-Möglichkeiten in NiceGUI via HTML-Canvas und Tk Canvas |
| | | |
| | | ## Install |
| | | |
| | | ```bash |
| | | python3.13 -m venv .venv |
| | | source .venv/bin/activate |
| | | pip install -r requirements.txt |
| | | ``` |
| | | |
| | | |
| | | ## Run |
| | | |
| | | In beide Programm kann man 4 Punkten einer (Kubischen) Bezier-Kurve mit Mouse-Klicks bestimmen, |
| | | danach wird eine Kurve angezeigt. |
| | | |
| | | ### Tk |
| | | |
| | | ```bash |
| | | python ./main-canvas.py |
| | | ``` |
| | | |
| | | ### NiceGUI |
| | | |
| | | ```bash |
| | | python ./main-nicegui.py |
| | | ``` |
New file |
| | |
| | | """" |
| | | Module related to bezier curve |
| | | """ |
| | | def make_cubic_bezier(control_points: [(float, float)], n: int = 10) -> [(float, float)]: |
| | | r"""" |
| | | 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 |
| | | |
New file |
| | |
| | | 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 |
New file |
| | |
| | | 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() |
New file |
| | |
| | | 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() |
| | | |
| | |
| | | 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) |
| | | |
| | |
| | | avg: Callable[[Scale], float] = \ |
| | | lambda v: sum(v) / len(v) if len(v) > 0 else 0.0 |
| | | |
| | | """ |
| | |
| | | \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 |
| | | |
| | |
| | | |
| | | |
| | | \begin{frame}[fragile] |
| | | \frametitle{Funktionsparameter} |
| | | \frametitle{Generic} |
| | | |
| | | \begin{minted}{python} |
| | | def avg(values: Sequence[int | float]) -> float: |
| | |
| | | \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] |