Source code for scitex_stats.auto._stat_style
#!/usr/bin/env python3
# Timestamp: "2026-01-24 (ywatanabe)"
# File: scitex_stats/auto/_stat_style.py
"""StatStyle dataclass for statistical reporting."""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Dict, List, Literal, Optional, Tuple
OutputTarget = Literal["latex", "html", "plain"]
__all__ = ["StatStyle", "OutputTarget"]
[docs]
@dataclass
class StatStyle:
"""Style configuration for statistical reporting.
Defines how to format statistical results for a specific journal
or output format.
Parameters
----------
id : str
Unique identifier for this style.
label : str
Human-readable label (e.g., "APA (LaTeX)").
target : OutputTarget
Output format: "latex", "html", or "plain".
stat_symbol_format : dict
Maps statistic symbols to their formatted versions.
p_format : str
Format string for p-values.
alpha_thresholds : list of (float, str)
P-value thresholds for stars.
effect_label_format : dict
Maps effect size names to their formatted labels.
n_format : str
Format string for sample sizes.
decimal_places_p : int
Decimal places for p-values.
decimal_places_stat : int
Decimal places for test statistics.
decimal_places_effect : int
Decimal places for effect sizes.
"""
id: str
label: str
target: OutputTarget
stat_symbol_format: Dict[str, str] = field(default_factory=dict)
p_format: str = "p = {p:.3f}"
alpha_thresholds: List[Tuple[float, str]] = field(default_factory=list)
effect_label_format: Dict[str, str] = field(default_factory=dict)
n_format: str = "n_{%s} = %d"
decimal_places_p: int = 3
decimal_places_stat: int = 2
decimal_places_effect: int = 2
[docs]
def format_stat(
self,
symbol: str,
value: float,
df: Optional[float] = None,
) -> str:
"""Format a test statistic.
Parameters
----------
symbol : str
Statistic symbol (e.g., "t", "F", "chi2").
value : float
Statistic value.
df : float, optional
Degrees of freedom.
Returns
-------
str
Formatted statistic string.
"""
fmt_symbol = self.stat_symbol_format.get(symbol, symbol)
dp = self.decimal_places_stat
if df is not None:
return f"{fmt_symbol}({df:.1f}) = {value:.{dp}f}"
return f"{fmt_symbol} = {value:.{dp}f}"
[docs]
def format_p(self, p_value: float) -> str:
"""Format a p-value.
Parameters
----------
p_value : float
P-value to format.
Returns
-------
str
Formatted p-value string.
"""
p_symbol = self.stat_symbol_format.get("p", "p")
dp = self.decimal_places_p
if p_value < 0.001:
return f"{p_symbol} < 0.001"
if p_value < 0.0001:
return f"{p_symbol} < 0.0001"
return f"{p_symbol} = {p_value:.{dp}f}"
[docs]
def format_effect(self, name: str, value: float) -> str:
"""Format an effect size.
Parameters
----------
name : str
Effect size name (e.g., "cohens_d_ind").
value : float
Effect size value.
Returns
-------
str
Formatted effect size string.
"""
label = self.effect_label_format.get(name, name)
dp = self.decimal_places_effect
return f"{label} = {value:.{dp}f}"
[docs]
def format_n(self, group: str, n: int) -> str:
"""Format a sample size.
Parameters
----------
group : str
Group name/label.
n : int
Sample size.
Returns
-------
str
Formatted sample size string.
"""
if "%s" in self.n_format:
return self.n_format % (group, n)
return self.n_format % n
[docs]
def p_to_stars(self, p_value: float) -> str:
"""Convert p-value to significance stars.
Parameters
----------
p_value : float
P-value.
Returns
-------
str
Stars string ("***", "**", "*", or "ns").
"""
if p_value is None:
return "ns"
for threshold, stars in self.alpha_thresholds:
if p_value < threshold:
return stars
return "ns"
# EOF