1

Ajoute l'analyse des pièces rares

This commit is contained in:
2025-12-02 16:52:42 +01:00
parent 16e1e958e0
commit 231a9af28d
7 changed files with 534 additions and 0 deletions

169
tests/test_rare_parts.py Normal file
View File

@@ -0,0 +1,169 @@
"""Tests du calcul des pièces rares."""
import csv
from pathlib import Path
from lib.rebrickable.rare_parts import build_rare_parts, write_rare_parts_by_set, write_rare_parts_list
def write_csv(path: Path, headers: list[str], rows: list[list[str]]) -> None:
"""Écrit un CSV simple pour les besoins de tests."""
with path.open("w", newline="") as csv_file:
writer = csv.writer(csv_file)
writer.writerow(headers)
writer.writerows(rows)
def test_build_rare_parts_detects_exclusive_variations(tmp_path: Path) -> None:
"""Identifie les combinaisons pièce+couleur présentes dans un seul set."""
parts_filtered = tmp_path / "parts_filtered.csv"
write_csv(
parts_filtered,
[
"part_num",
"color_rgb",
"is_translucent",
"set_num",
"set_id",
"year",
"quantity_in_set",
"is_spare",
"is_minifig_part",
],
[
["p1", "AAAAAA", "false", "1000-1", "1000", "2020", "2", "false", "false"],
["p1", "AAAAAA", "false", "2000-1", "2000", "2021", "3", "false", "false"],
["p2", "BBBBBB", "false", "1000-1", "1000", "2020", "1", "false", "true"],
["p3", "CCCCCC", "true", "2000-1", "2000", "2021", "4", "false", "false"],
],
)
sets_enriched = tmp_path / "sets_enriched.csv"
write_csv(
sets_enriched,
["set_num", "set_id", "name", "year", "in_collection"],
[
["1000-1", "1000", "Set A", "2020", "true"],
["2000-1", "2000", "Set B", "2021", "false"],
],
)
parts_catalog = tmp_path / "parts.csv"
write_csv(
parts_catalog,
["part_num", "name", "part_cat_id"],
[
["p1", "Brick 1x1", "1"],
["p2", "Head Custom", "59"],
["p3", "Slope 45", "2"],
],
)
colors = tmp_path / "colors.csv"
write_csv(
colors,
["id", "name", "rgb", "is_trans", "num_parts", "num_sets", "y1", "y2"],
[
["1", "Gray", "AAAAAA", "false", "0", "0", "0", "0"],
["2", "Blue", "BBBBBB", "false", "0", "0", "0", "0"],
["3", "Trans-Clear", "CCCCCC", "true", "0", "0", "0", "0"],
],
)
rare_parts, rare_by_set = build_rare_parts(parts_filtered, sets_enriched, parts_catalog, colors)
assert rare_parts == [
{
"set_num": "1000-1",
"set_id": "1000",
"set_name": "Set A",
"year": "2020",
"part_num": "p2",
"part_name": "Head Custom",
"part_cat_id": "59",
"color_rgb": "BBBBBB",
"color_name": "Blue",
"is_translucent": "false",
"is_minifig_part": "true",
"quantity_in_set": "1",
"in_collection": "true",
},
{
"set_num": "2000-1",
"set_id": "2000",
"set_name": "Set B",
"year": "2021",
"part_num": "p3",
"part_name": "Slope 45",
"part_cat_id": "2",
"color_rgb": "CCCCCC",
"color_name": "Trans-Clear",
"is_translucent": "true",
"is_minifig_part": "false",
"quantity_in_set": "4",
"in_collection": "false",
},
]
assert rare_by_set == [
{
"set_num": "1000-1",
"set_id": "1000",
"name": "Set A",
"year": "2020",
"in_collection": "true",
"rare_parts_distinct": "1",
"rare_parts_quantity": "1",
"rare_minifig_parts_distinct": "1",
"rare_minifig_quantity": "1",
},
{
"set_num": "2000-1",
"set_id": "2000",
"name": "Set B",
"year": "2021",
"in_collection": "false",
"rare_parts_distinct": "1",
"rare_parts_quantity": "4",
"rare_minifig_parts_distinct": "0",
"rare_minifig_quantity": "0",
},
]
def test_write_rare_parts_outputs_csv(tmp_path: Path) -> None:
"""Sérialise les pièces rares et lagrégat par set."""
rare_parts_path = tmp_path / "rare_parts.csv"
rare_by_set_path = tmp_path / "rare_parts_by_set.csv"
rare_parts_sample = [
{
"set_num": "123-1",
"set_id": "123",
"set_name": "Sample",
"year": "2020",
"part_num": "p1",
"part_name": "Brick",
"part_cat_id": "1",
"color_rgb": "FFFFFF",
"color_name": "White",
"is_translucent": "false",
"is_minifig_part": "false",
"quantity_in_set": "2",
"in_collection": "true",
}
]
rare_by_set_sample = [
{
"set_num": "123-1",
"set_id": "123",
"name": "Sample",
"year": "2020",
"in_collection": "true",
"rare_parts_distinct": "1",
"rare_parts_quantity": "2",
"rare_minifig_parts_distinct": "0",
"rare_minifig_quantity": "0",
}
]
write_rare_parts_list(rare_parts_path, rare_parts_sample)
write_rare_parts_by_set(rare_by_set_path, rare_by_set_sample)
assert rare_parts_path.exists()
assert rare_by_set_path.exists()