Update testing-telos.md with relative asset paths and refined content. Add generated PNGs: telos-feature-iteration.png, telos-invariance-testing.png, telos-cross-cutting.png, telos-targeted-concerns.png. Introduce pyproject.toml and poetry.lock for diagram generation dependencies. Add svg-to-png.py script for generating diagrams. Rename drafts/testing-telos.html to references/testing-telos.html.
105 lines
3.3 KiB
Python
105 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Testing Telos - Diagram PNG Generator
|
||
=====================================
|
||
Generates the four high-resolution PNG diagrams for the "Testing Telos" blog post.
|
||
Saves them directly into an `assets/` folder (created automatically if missing).
|
||
|
||
Run this script once in the root of your work-blog repository:
|
||
python3 generate-telos-diagrams.py
|
||
|
||
It will produce:
|
||
assets/telos-feature-iteration.png
|
||
assets/telos-invariance-testing.png
|
||
assets/telos-cross-cutting.png
|
||
assets/telos-targeted-concerns.png
|
||
|
||
All images are 260×260 px at 300 DPI for crisp rendering on the blog.
|
||
"""
|
||
|
||
import matplotlib.pyplot as plt
|
||
from matplotlib.patches import Polygon, Circle
|
||
import numpy as np
|
||
import os
|
||
|
||
# Ensure assets/ directory exists
|
||
os.makedirs("assets", exist_ok=True)
|
||
DPI = 300
|
||
SIZE = 260
|
||
|
||
def save_fig(fig, filename):
|
||
"""Save figure with consistent styling and transparency."""
|
||
fig.savefig(f"assets/{filename}", dpi=DPI, bbox_inches="tight", pad_inches=0.02, transparent=True)
|
||
plt.close(fig)
|
||
print(f"✓ Generated: assets/{filename}")
|
||
|
||
# 1. Feature Iteration — The Triangle (Pyramid)
|
||
fig1, ax1 = plt.subplots(figsize=(SIZE/100, SIZE/100))
|
||
ax1.set_xlim(0, 100)
|
||
ax1.set_ylim(0, 105)
|
||
ax1.set_aspect("equal")
|
||
ax1.axis("off")
|
||
|
||
# Main pyramid triangle
|
||
triangle = Polygon([[50, 12], [92, 92], [8, 92]], closed=True,
|
||
facecolor="#F8E4C4", edgecolor="#A07828", linewidth=6)
|
||
ax1.add_patch(triangle)
|
||
|
||
# Unit-test layer line (widest)
|
||
ax1.plot([22, 78], [73, 73], color="#A07828", linewidth=3)
|
||
|
||
# Integration-test layer line (middle)
|
||
ax1.plot([35, 65], [46, 46], color="#A07828", linewidth=3)
|
||
|
||
save_fig(fig1, "telos-feature-iteration.png")
|
||
|
||
# 2. Invariance Testing — The Bullseye
|
||
fig2, ax2 = plt.subplots(figsize=(SIZE/100, SIZE/100))
|
||
ax2.set_xlim(0, 100)
|
||
ax2.set_ylim(0, 100)
|
||
ax2.set_aspect("equal")
|
||
ax2.axis("off")
|
||
|
||
# Outermost ring
|
||
ax2.add_patch(Circle((50, 50), 44, facecolor="#D4B896", edgecolor="#A07828", linewidth=4))
|
||
# Middle ring
|
||
ax2.add_patch(Circle((50, 50), 29, facecolor="#C4A276", edgecolor="#8B7560", linewidth=4))
|
||
# Innermost ring
|
||
ax2.add_patch(Circle((50, 50), 14, facecolor="#A0522D", edgecolor="#7A3E20", linewidth=4))
|
||
|
||
save_fig(fig2, "telos-invariance-testing.png")
|
||
|
||
# 3. Cross-Cutting Structural Changes — The Diamond
|
||
fig3, ax3 = plt.subplots(figsize=(SIZE/100, SIZE/100))
|
||
ax3.set_xlim(0, 100)
|
||
ax3.set_ylim(0, 100)
|
||
ax3.set_aspect("equal")
|
||
ax3.axis("off")
|
||
|
||
diamond_points = [[50, 6], [94, 50], [50, 94], [6, 50]]
|
||
diamond = Polygon(diamond_points, closed=True,
|
||
facecolor="#7BA085", edgecolor="#5A7A63", linewidth=6)
|
||
ax3.add_patch(diamond)
|
||
|
||
save_fig(fig3, "telos-cross-cutting.png")
|
||
|
||
# 4. Targeted Non-Functional Concerns — The Star
|
||
fig4, ax4 = plt.subplots(figsize=(SIZE/100, SIZE/100))
|
||
ax4.set_xlim(0, 100)
|
||
ax4.set_ylim(0, 100)
|
||
ax4.set_aspect("equal")
|
||
ax4.axis("off")
|
||
|
||
# Star vertices (10-pointed star)
|
||
star_points = np.array([
|
||
[50, 4], [61, 36], [96, 36], [68, 58], [78, 92],
|
||
[50, 72], [22, 92], [32, 58], [4, 36], [39, 36]
|
||
])
|
||
star = Polygon(star_points, closed=True,
|
||
facecolor="#C07060", edgecolor="#8B4040", linewidth=6)
|
||
ax4.add_patch(star)
|
||
|
||
save_fig(fig4, "telos-targeted-concerns.png")
|
||
|
||
print("\n🎉 All four Testing Telos PNG diagrams have been generated successfully!")
|
||
print(" They are now ready to be referenced in your Markdown post.") |