...
`` ou ``""`` si stratification absente.
"""
if not stratified_ranking or not available_strata:
return ""
labels = labels or {}
caption = labels.get(
"stratification_caption",
"Classement par strate (script_type)",
)
description = labels.get(
"stratification_description",
"Le tableau global classe sur l'ensemble du corpus. Quand le "
"corpus est hétérogène, certains moteurs dominent sur un type "
"de document et perdent sur un autre — la vue stratifiée le "
"révèle.",
)
engine_label = labels.get("col_engine", "Moteur")
median_label = labels.get("stratification_median_label", "Médiane CER")
mean_label = labels.get("stratification_mean_label", "Moyenne CER")
docs_label = labels.get("stratification_docs_label", "Documents")
no_data = labels.get("stratification_no_data_label", "—")
n_docs_in_stratum_label = labels.get(
"stratification_n_docs_label", "documents",
)
parts: list[str] = []
parts.append('')
parts.append(
f'
{_e(caption)}
'
)
parts.append(
f'
{_e(description)}
'
)
# Bandeau d'hétérogénéité si disponible
if homogeneity and homogeneity.get("max_inter_strata_gap") is not None:
gap = float(homogeneity["max_inter_strata_gap"])
leader = str(homogeneity.get("leader") or "")
min_strat, max_strat = homogeneity.get(
"leader_max_gap_strata", ["", ""]
)
gap_template = labels.get(
"stratification_gap_summary",
"Écart inter-strate du leader {leader} : {gap_pct} points "
"de CER médian (entre « {min_stratum} » et « {max_stratum} »).",
)
gap_text = gap_template.format(
leader=leader,
gap_pct=f"{gap * 100:.1f}",
min_stratum=min_strat,
max_stratum=max_strat,
)
# gap_text contient déjà des données utilisateur — on n'échappe pas
# le template lui-même (i18n connue), mais on n'injecte pas non plus
# de markup. _e() est appliqué aux variables via format() côté template.
parts.append(
f'
⚠ {_e(gap_text)}
'
)
# Une ``
`` par strate (premier ouvert pour donner le contexte)
for i, stratum in enumerate(available_strata):
entries = stratified_ranking.get(stratum) or []
n_docs_total = max((int(e.get("documents") or 0) for e in entries), default=0)
open_attr = " open" if i == 0 else ""
parts.append(
f''
)
parts.append(
f''
f'{_e(stratum)} '
f'({n_docs_total} {_e(n_docs_in_stratum_label)})'
f'
'
)
parts.append(
''
)
parts.append("")
for hdr in (engine_label, median_label, mean_label, docs_label):
parts.append(
f'| '
f'{_e(hdr)} | '
)
parts.append("
")
for entry in entries:
engine = str(entry.get("engine", ""))
median = entry.get("median_cer")
mean = entry.get("mean_cer")
n_docs = int(entry.get("documents") or 0)
bg = color_traffic_light(float(median), low_is_good=True, scale_max=0.30) if median is not None else "#f4f4f4"
parts.append("")
parts.append(
f'| '
f'{_e(engine)} | '
)
parts.append(
f''
f'{_e(_format_cer(median)) if median is not None else _e(no_data)}'
f' | '
)
parts.append(
f''
f'{_e(_format_cer(mean)) if mean is not None else _e(no_data)}'
f' | '
)
parts.append(
f'{n_docs} | '
)
parts.append("
")
parts.append("
")
parts.append(" ")
parts.append(" ")
return "".join(parts)
__all__ = [
"build_stratified_ranking_html",
]