mirror of
https://github.com/kuhyx/testsAndMisc-archive.git
synced 2026-07-04 13:23:01 +02:00
refactor(praca/generate_images): fix ruff violations in generate_q9_all_diagrams.py
This commit is contained in:
parent
42d0f42fa3
commit
9340ca6729
@ -4,6 +4,11 @@
|
|||||||
Replaces every ASCII diagram with a monochrome A4-printable PNG (300 DPI).
|
Replaces every ASCII diagram with a monochrome A4-printable PNG (300 DPI).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import matplotlib as mpl
|
import matplotlib as mpl
|
||||||
|
|
||||||
mpl.use("Agg")
|
mpl.use("Agg")
|
||||||
@ -14,6 +19,12 @@ from matplotlib.patches import FancyBboxPatch
|
|||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from matplotlib.axes import Axes
|
||||||
|
from matplotlib.figure import Figure
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
DPI = 300
|
DPI = 300
|
||||||
BG = "white"
|
BG = "white"
|
||||||
LN = "black"
|
LN = "black"
|
||||||
@ -29,24 +40,26 @@ GRAY2 = "#D0D0D0"
|
|||||||
GRAY3 = "#B8B8B8"
|
GRAY3 = "#B8B8B8"
|
||||||
GRAY4 = "#F5F5F5"
|
GRAY4 = "#F5F5F5"
|
||||||
GRAY5 = "#C0C0C0"
|
GRAY5 = "#C0C0C0"
|
||||||
|
OCCUPIED_SLOTS = 2
|
||||||
|
|
||||||
|
|
||||||
def draw_box(
|
def draw_box(
|
||||||
ax,
|
ax: Axes,
|
||||||
x,
|
x: float,
|
||||||
y,
|
y: float,
|
||||||
w,
|
w: float,
|
||||||
h,
|
h: float,
|
||||||
text,
|
text: str,
|
||||||
fill="white",
|
fill: str = "white",
|
||||||
lw=1.2,
|
lw: float = 1.2,
|
||||||
fontsize=FS,
|
fontsize: float = FS,
|
||||||
fontweight="normal",
|
fontweight: str = "normal",
|
||||||
ha="center",
|
ha: str = "center",
|
||||||
va="center",
|
va: str = "center",
|
||||||
rounded=True,
|
*,
|
||||||
edgecolor=LN,
|
rounded: bool = True,
|
||||||
linestyle="-",
|
edgecolor: str = LN,
|
||||||
|
linestyle: str = "-",
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Draw box."""
|
"""Draw box."""
|
||||||
if rounded:
|
if rounded:
|
||||||
@ -83,7 +96,16 @@ def draw_box(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def draw_arrow(ax, x1, y1, x2, y2, lw=1.2, style="->", color=LN) -> None:
|
def draw_arrow(
|
||||||
|
ax: Axes,
|
||||||
|
x1: float,
|
||||||
|
y1: float,
|
||||||
|
x2: float,
|
||||||
|
y2: float,
|
||||||
|
lw: float = 1.2,
|
||||||
|
style: str = "->",
|
||||||
|
color: str = LN,
|
||||||
|
) -> None:
|
||||||
"""Draw arrow."""
|
"""Draw arrow."""
|
||||||
ax.annotate(
|
ax.annotate(
|
||||||
"",
|
"",
|
||||||
@ -93,7 +115,15 @@ def draw_arrow(ax, x1, y1, x2, y2, lw=1.2, style="->", color=LN) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def draw_double_arrow(ax, x1, y1, x2, y2, lw=1.2, color=LN) -> None:
|
def draw_double_arrow(
|
||||||
|
ax: Axes,
|
||||||
|
x1: float,
|
||||||
|
y1: float,
|
||||||
|
x2: float,
|
||||||
|
y2: float,
|
||||||
|
lw: float = 1.2,
|
||||||
|
color: str = LN,
|
||||||
|
) -> None:
|
||||||
"""Draw double arrow."""
|
"""Draw double arrow."""
|
||||||
ax.annotate(
|
ax.annotate(
|
||||||
"",
|
"",
|
||||||
@ -103,26 +133,26 @@ def draw_double_arrow(ax, x1, y1, x2, y2, lw=1.2, color=LN) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def save_fig(fig, name) -> None:
|
def save_fig(fig: Figure, name: str) -> None:
|
||||||
"""Save fig."""
|
"""Save fig."""
|
||||||
path = str(Path(OUTPUT_DIR) / name)
|
path = str(Path(OUTPUT_DIR) / name)
|
||||||
fig.savefig(path, dpi=DPI, bbox_inches="tight", facecolor=BG, pad_inches=0.15)
|
fig.savefig(path, dpi=DPI, bbox_inches="tight", facecolor=BG, pad_inches=0.15)
|
||||||
plt.close(fig)
|
plt.close(fig)
|
||||||
print(f" Saved: {path}")
|
_logger.info(" Saved: %s", path)
|
||||||
|
|
||||||
|
|
||||||
def draw_table(
|
def draw_table(
|
||||||
ax,
|
ax: Axes,
|
||||||
headers,
|
headers: list[str],
|
||||||
rows,
|
rows: list[list[str]],
|
||||||
x0,
|
x0: float,
|
||||||
y0,
|
y0: float,
|
||||||
col_widths,
|
col_widths: list[float],
|
||||||
row_h=0.4,
|
row_h: float = 0.4,
|
||||||
header_fill=GRAY2,
|
header_fill: str = GRAY2,
|
||||||
row_fills=None,
|
row_fills: list[str] | None = None,
|
||||||
fontsize=FS,
|
fontsize: float = FS,
|
||||||
header_fontsize=None,
|
header_fontsize: float | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Draw a clean table on axes."""
|
"""Draw a clean table on axes."""
|
||||||
if header_fontsize is None:
|
if header_fontsize is None:
|
||||||
@ -540,7 +570,7 @@ def gen_speed_comparison() -> None:
|
|||||||
fontweight="bold",
|
fontweight="bold",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Left: creation
|
# Creation time panel
|
||||||
ax = axes[0]
|
ax = axes[0]
|
||||||
ops = ["fork()\n(nowy proces)", "pthread_create()\n(nowy wątek)"]
|
ops = ["fork()\n(nowy proces)", "pthread_create()\n(nowy wątek)"]
|
||||||
times = [3.0, 0.05] # ms
|
times = [3.0, 0.05] # ms
|
||||||
@ -1177,15 +1207,8 @@ def gen_starvation_priority() -> None:
|
|||||||
# ============================================================
|
# ============================================================
|
||||||
# 14. Bounded buffer + readers-writers + philosophers
|
# 14. Bounded buffer + readers-writers + philosophers
|
||||||
# ============================================================
|
# ============================================================
|
||||||
def gen_classic_problems() -> None:
|
def _draw_bounded_buffer_panel(ax: Axes) -> None:
|
||||||
"""Gen classic problems."""
|
"""Draw the bounded-buffer (producer-consumer) panel."""
|
||||||
fig, axes = plt.subplots(1, 3, figsize=(12, 5))
|
|
||||||
fig.suptitle(
|
|
||||||
"Klasyczne problemy synchronizacji", fontsize=FS_TITLE, fontweight="bold"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Panel 1: Bounded Buffer with semaphores
|
|
||||||
ax = axes[0]
|
|
||||||
ax.set_xlim(0, 8)
|
ax.set_xlim(0, 8)
|
||||||
ax.set_ylim(0, 7)
|
ax.set_ylim(0, 7)
|
||||||
ax.set_aspect("auto")
|
ax.set_aspect("auto")
|
||||||
@ -1204,7 +1227,6 @@ def gen_classic_problems() -> None:
|
|||||||
fill=GRAY1,
|
fill=GRAY1,
|
||||||
fontsize=5.5,
|
fontsize=5.5,
|
||||||
)
|
)
|
||||||
# Buffer
|
|
||||||
items = ["A", "B", "", ""]
|
items = ["A", "B", "", ""]
|
||||||
for i, item in enumerate(items):
|
for i, item in enumerate(items):
|
||||||
x = 2.8 + i * 0.9
|
x = 2.8 + i * 0.9
|
||||||
@ -1235,7 +1257,6 @@ def gen_classic_problems() -> None:
|
|||||||
draw_arrow(ax, 2.2, 4.6, 2.8, 4.65, lw=1.2)
|
draw_arrow(ax, 2.2, 4.6, 2.8, 4.65, lw=1.2)
|
||||||
draw_arrow(ax, 6.4, 4.65, 6.0, 4.6, lw=1.2)
|
draw_arrow(ax, 6.4, 4.65, 6.0, 4.6, lw=1.2)
|
||||||
|
|
||||||
# Semaphores
|
|
||||||
sems = [("mutex = 1", GRAY2), ("empty = N", GRAY1), ("full = 0", GRAY3)]
|
sems = [("mutex = 1", GRAY2), ("empty = N", GRAY1), ("full = 0", GRAY3)]
|
||||||
for i, (s, c) in enumerate(sems):
|
for i, (s, c) in enumerate(sems):
|
||||||
draw_box(
|
draw_box(
|
||||||
@ -1261,8 +1282,9 @@ def gen_classic_problems() -> None:
|
|||||||
bbox={"boxstyle": "round", "facecolor": "#F8D7DA", "edgecolor": "#C62828"},
|
bbox={"boxstyle": "round", "facecolor": "#F8D7DA", "edgecolor": "#C62828"},
|
||||||
)
|
)
|
||||||
|
|
||||||
# Panel 2: Readers-Writers
|
|
||||||
ax = axes[1]
|
def _draw_readers_writers_panel(ax: Axes) -> None:
|
||||||
|
"""Draw the readers-writers panel."""
|
||||||
ax.set_xlim(0, 8)
|
ax.set_xlim(0, 8)
|
||||||
ax.set_ylim(0, 7)
|
ax.set_ylim(0, 7)
|
||||||
ax.set_aspect("auto")
|
ax.set_aspect("auto")
|
||||||
@ -1271,7 +1293,6 @@ def gen_classic_problems() -> None:
|
|||||||
"Czytelnicy-Pisarze\n(Readers-Writers)", fontsize=FS, fontweight="bold"
|
"Czytelnicy-Pisarze\n(Readers-Writers)", fontsize=FS, fontweight="bold"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Resource
|
|
||||||
draw_box(
|
draw_box(
|
||||||
ax,
|
ax,
|
||||||
2.5,
|
2.5,
|
||||||
@ -1284,7 +1305,6 @@ def gen_classic_problems() -> None:
|
|||||||
fontweight="bold",
|
fontweight="bold",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Readers
|
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
x = 0.3 + i * 1.0
|
x = 0.3 + i * 1.0
|
||||||
draw_box(
|
draw_box(
|
||||||
@ -1309,7 +1329,6 @@ def gen_classic_problems() -> None:
|
|||||||
fontweight="bold",
|
fontweight="bold",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Writer
|
|
||||||
draw_box(
|
draw_box(
|
||||||
ax, 5.5, 5.5, 1.5, 0.7, "Pisarz", fill=GRAY5, fontsize=FS, fontweight="bold"
|
ax, 5.5, 5.5, 1.5, 0.7, "Pisarz", fill=GRAY5, fontsize=FS, fontweight="bold"
|
||||||
)
|
)
|
||||||
@ -1324,7 +1343,6 @@ def gen_classic_problems() -> None:
|
|||||||
color="#C62828",
|
color="#C62828",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Rules
|
|
||||||
rules = [
|
rules = [
|
||||||
"Wielu czytelników = OK",
|
"Wielu czytelników = OK",
|
||||||
"Jeden pisarz = wyłączny",
|
"Jeden pisarz = wyłączny",
|
||||||
@ -1343,8 +1361,9 @@ def gen_classic_problems() -> None:
|
|||||||
bbox={"boxstyle": "round,pad=0.2", "facecolor": GRAY4, "edgecolor": GRAY3},
|
bbox={"boxstyle": "round,pad=0.2", "facecolor": GRAY4, "edgecolor": GRAY3},
|
||||||
)
|
)
|
||||||
|
|
||||||
# Panel 3: Dining Philosophers
|
|
||||||
ax = axes[2]
|
def _draw_philosophers_panel(ax: Axes) -> None:
|
||||||
|
"""Draw the dining-philosophers panel."""
|
||||||
ax.set_xlim(0, 8)
|
ax.set_xlim(0, 8)
|
||||||
ax.set_ylim(0, 7)
|
ax.set_ylim(0, 7)
|
||||||
ax.set_aspect("auto")
|
ax.set_aspect("auto")
|
||||||
@ -1353,13 +1372,11 @@ def gen_classic_problems() -> None:
|
|||||||
"Ucztujący filozofowie\n(Dining Philosophers)", fontsize=FS, fontweight="bold"
|
"Ucztujący filozofowie\n(Dining Philosophers)", fontsize=FS, fontweight="bold"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Draw circular table
|
|
||||||
cx, cy, r = 4.0, 3.8, 1.8
|
cx, cy, r = 4.0, 3.8, 1.8
|
||||||
table = plt.Circle((cx, cy), 0.8, fill=True, facecolor=GRAY2, edgecolor=LN, lw=1.5)
|
table = plt.Circle((cx, cy), 0.8, fill=True, facecolor=GRAY2, edgecolor=LN, lw=1.5)
|
||||||
ax.add_patch(table)
|
ax.add_patch(table)
|
||||||
ax.text(cx, cy, "Stół", fontsize=FS, ha="center", fontweight="bold")
|
ax.text(cx, cy, "Stół", fontsize=FS, ha="center", fontweight="bold")
|
||||||
|
|
||||||
# 5 philosophers around table
|
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
angle = np.pi / 2 + i * 2 * np.pi / 5
|
angle = np.pi / 2 + i * 2 * np.pi / 5
|
||||||
px = cx + r * np.cos(angle)
|
px = cx + r * np.cos(angle)
|
||||||
@ -1372,7 +1389,6 @@ def gen_classic_problems() -> None:
|
|||||||
px, py, f"F{i}", ha="center", va="center", fontsize=FS, fontweight="bold"
|
px, py, f"F{i}", ha="center", va="center", fontsize=FS, fontweight="bold"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Fork between philosophers
|
|
||||||
fork_angle = np.pi / 2 + (i + 0.5) * 2 * np.pi / 5
|
fork_angle = np.pi / 2 + (i + 0.5) * 2 * np.pi / 5
|
||||||
fx = cx + (r * 0.6) * np.cos(fork_angle)
|
fx = cx + (r * 0.6) * np.cos(fork_angle)
|
||||||
fy = cy + (r * 0.6) * np.sin(fork_angle)
|
fy = cy + (r * 0.6) * np.sin(fork_angle)
|
||||||
@ -1385,7 +1401,6 @@ def gen_classic_problems() -> None:
|
|||||||
)
|
)
|
||||||
ax.text(fx + 0.2, fy + 0.15, f"w{i}", fontsize=5, color="#555555")
|
ax.text(fx + 0.2, fy + 0.15, f"w{i}", fontsize=5, color="#555555")
|
||||||
|
|
||||||
# Rules
|
|
||||||
rules = [
|
rules = [
|
||||||
"Jedzenie = 2 widelce",
|
"Jedzenie = 2 widelce",
|
||||||
"Naiwne → DEADLOCK",
|
"Naiwne → DEADLOCK",
|
||||||
@ -1395,6 +1410,21 @@ def gen_classic_problems() -> None:
|
|||||||
for i, r in enumerate(rules):
|
for i, r in enumerate(rules):
|
||||||
ax.text(4.0, 1.2 - i * 0.35, r, fontsize=FS_SMALL, ha="center")
|
ax.text(4.0, 1.2 - i * 0.35, r, fontsize=FS_SMALL, ha="center")
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# 14. Bounded buffer + readers-writers + philosophers
|
||||||
|
# ============================================================
|
||||||
|
def gen_classic_problems() -> None:
|
||||||
|
"""Gen classic problems."""
|
||||||
|
fig, axes = plt.subplots(1, 3, figsize=(12, 5))
|
||||||
|
fig.suptitle(
|
||||||
|
"Klasyczne problemy synchronizacji", fontsize=FS_TITLE, fontweight="bold"
|
||||||
|
)
|
||||||
|
|
||||||
|
_draw_bounded_buffer_panel(axes[0])
|
||||||
|
_draw_readers_writers_panel(axes[1])
|
||||||
|
_draw_philosophers_panel(axes[2])
|
||||||
|
|
||||||
fig.tight_layout(rect=[0, 0, 1, 0.88])
|
fig.tight_layout(rect=[0, 0, 1, 0.88])
|
||||||
save_fig(fig, "q9_classic_problems.png")
|
save_fig(fig, "q9_classic_problems.png")
|
||||||
|
|
||||||
@ -1523,7 +1553,7 @@ def gen_semaphore_concept() -> None:
|
|||||||
# Parking slots
|
# Parking slots
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
x = 2.0 + i * 2.0
|
x = 2.0 + i * 2.0
|
||||||
occupied = i < 2 # 2 occupied, 1 free
|
occupied = i < OCCUPIED_SLOTS
|
||||||
fill = GRAY3 if occupied else "white"
|
fill = GRAY3 if occupied else "white"
|
||||||
label = f"Wątek {i + 1}" if occupied else "(wolne)"
|
label = f"Wątek {i + 1}" if occupied else "(wolne)"
|
||||||
draw_box(
|
draw_box(
|
||||||
@ -1578,7 +1608,7 @@ def gen_semaphore_concept() -> None:
|
|||||||
# MAIN — generate all
|
# MAIN — generate all
|
||||||
# ============================================================
|
# ============================================================
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print("Generating ALL PYTANIE 9 diagrams...")
|
_logger.info("Generating ALL PYTANIE 9 diagrams...")
|
||||||
gen_process_vs_thread()
|
gen_process_vs_thread()
|
||||||
gen_memory_layout()
|
gen_memory_layout()
|
||||||
gen_process_states()
|
gen_process_states()
|
||||||
@ -1595,4 +1625,4 @@ if __name__ == "__main__":
|
|||||||
gen_classic_problems()
|
gen_classic_problems()
|
||||||
gen_sync_comparison()
|
gen_sync_comparison()
|
||||||
gen_semaphore_concept()
|
gen_semaphore_concept()
|
||||||
print("\nAll 16 PYTANIE 9 diagrams generated successfully!")
|
_logger.info("All 16 PYTANIE 9 diagrams generated successfully!")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user