1

Ajoute les agrégats et visualisations globales des couleurs de têtes

This commit is contained in:
2025-12-01 23:56:03 +01:00
parent ba76030d36
commit b271e0ebdd
12 changed files with 502 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
"""Tests de l'agrégation globale des têtes de minifigs."""
import csv
from pathlib import Path
from lib.rebrickable.global_minifig_heads import (
aggregate_global_heads_by_year,
write_global_heads_by_year,
)
def write_csv(path: Path, headers: list[str], rows: list[list[str]]) -> None:
"""Écrit un CSV simple pour les besoins des tests."""
with path.open("w", newline="") as csv_file:
writer = csv.writer(csv_file)
writer.writerow(headers)
writer.writerows(rows)
def test_aggregate_global_heads_by_year(tmp_path: Path) -> None:
"""Construit un agrégat global par année."""
inventories = tmp_path / "inventories.csv"
inventory_parts = tmp_path / "inventory_parts.csv"
parts = tmp_path / "parts.csv"
colors = tmp_path / "colors.csv"
sets = tmp_path / "sets.csv"
destination = tmp_path / "global_heads.csv"
write_csv(
inventories,
["id", "version", "set_num"],
[
["1", "1", "1000-1"],
["2", "2", "1000-1"],
["3", "1", "2000-1"],
],
)
write_csv(
inventory_parts,
["inventory_id", "part_num", "color_id", "quantity", "is_spare", "img_url"],
[
["2", "3626b", "1", "2", "False", ""],
["3", "3626b", "2", "1", "False", ""],
["3", "3001", "1", "10", "False", ""],
],
)
write_csv(
parts,
["part_num", "name", "part_cat_id", "part_material"],
[
["3626b", "Minifig Head", "59", "Plastic"],
["3001", "Brick 2 x 4", "11", "Plastic"],
],
)
write_csv(
colors,
["id", "name", "rgb", "is_trans", "num_parts", "num_sets", "y1", "y2"],
[
["1", "Yellow", "FFFF00", "False", "0", "0", "0", "0"],
["2", "Light Flesh", "FFE1BD", "False", "0", "0", "0", "0"],
],
)
write_csv(
sets,
["set_num", "name", "year", "theme_id", "num_parts", "img_url"],
[
["1000-1", "Set A", "2020", "1", "0", ""],
["2000-1", "Set B", "2021", "1", "0", ""],
],
)
rows = aggregate_global_heads_by_year(inventories, inventory_parts, parts, colors, sets)
write_global_heads_by_year(destination, rows)
with destination.open() as csv_file:
written = list(csv.DictReader(csv_file))
assert written == [
{
"year": "2020",
"color_rgb": "FFFF00",
"is_translucent": "false",
"color_name": "Yellow",
"quantity": "2",
},
{
"year": "2021",
"color_rgb": "FFE1BD",
"is_translucent": "false",
"color_name": "Light Flesh",
"quantity": "1",
},
]

View File

@@ -0,0 +1,28 @@
"""Tests des visualisations globales des têtes de minifigs."""
import matplotlib
from pathlib import Path
from lib.plots.global_minifig_heads import plot_global_head_shares
matplotlib.use("Agg")
def test_plot_global_head_shares(tmp_path: Path) -> None:
"""Génère un graphique de parts de couleur sur le catalogue complet."""
heads_path = tmp_path / "global_minifig_heads_by_year.csv"
destination = tmp_path / "figures" / "step17" / "global_minifig_heads_shares.png"
heads_path.write_text(
"year,color_rgb,is_translucent,color_name,quantity\n"
"2020,FFFF00,false,Yellow,2\n"
"2020,FFE1BD,false,Light Flesh,1\n"
"2021,FFE1BD,false,Light Flesh,3\n"
"2021,E7B68F,false,Medium Dark Flesh,1\n"
"2021,FFFF00,false,Yellow,2\n"
)
plot_global_head_shares(heads_path, destination)
assert destination.exists()
assert destination.stat().st_size > 0

View File

@@ -0,0 +1,29 @@
"""Tests du graphique global sur la part de têtes Yellow."""
import matplotlib
from pathlib import Path
from lib.plots.minifig_skin_tones import plot_yellow_share
matplotlib.use("Agg")
def test_plot_yellow_share(tmp_path: Path) -> None:
"""Génère un graphe de part Yellow sur le catalogue complet."""
heads_path = tmp_path / "global_minifig_heads_by_year.csv"
milestones_path = tmp_path / "milestones.csv"
destination = tmp_path / "figures" / "step17" / "global_minifig_heads_yellow_share.png"
heads_path.write_text(
"year,color_rgb,is_translucent,color_name,quantity\n"
"2020,FFFF00,false,Yellow,2\n"
"2020,FFE1BD,false,Light Flesh,1\n"
"2021,FFE1BD,false,Light Flesh,3\n"
"2021,FFFF00,false,Yellow,1\n"
)
milestones_path.write_text("year,description\n2020,Lancement\n")
plot_yellow_share(heads_path, milestones_path, destination)
assert destination.exists()
assert destination.stat().st_size > 0