"""Template: six functions of a dollar factor table.""" from __future__ import annotations from typing import Any from app.tools.coerce import num, pct def _f(p: dict[str, Any], key: str, default: float) -> float: """Tolerant numeric param; keys ending in `_pct` / starting with `taux` are ratios.""" raw = p.get(key) v = pct(raw, None) if (key.endswith("_pct") or key.startswith("taux")) else num(raw, None) return float(default) if v is None else v def build(p: dict[str, Any]) -> dict[str, Any]: rate = _f(p, "taux", 0.06) n_max = int(_f(p, "periodes_max", 30)) inputs = [{"cell": "B4", "label": "Taux périodique i", "value": rate, "format": "percent", "name": "Taux_i"}] rows = [] for n in range(1, n_max + 1): r = 7 + n rows.append([n, f"=(1+$B$4)^A{r}", f"=((1+$B$4)^A{r}-1)/$B$4", f"=$B$4/((1+$B$4)^A{r}-1)", f"=(1+$B$4)^-A{r}", f"=(1-(1+$B$4)^-A{r})/$B$4", f"=$B$4/(1-(1+$B$4)^-A{r})"]) table = { "anchor": "A7", "columns": [{"header": "n", "type": "integer"}, {"header": "VF de 1 $", "type": "factor"}, {"header": "VF annuité de 1 $", "type": "factor"}, {"header": "Fonds d'amortissement", "type": "factor"}, {"header": "VA de 1 $", "type": "factor"}, {"header": "VA annuité de 1 $", "type": "factor"}, {"header": "Recouvrement du capital", "type": "factor"}], "rows": rows, } return { "filename": p.get("filename", "six_fonctions_du_dollar.xlsx"), "style": "uqo", "sheets": [{ "name": "Six fonctions", "title": "Les six fonctions du dollar — table de facteurs", "inputs": inputs, "tables": [table], "notes": ["Colonnes 1-3 : capitalisation ; colonnes 4-6 : actualisation (réciproques).", "FRC = FA + i ; VA annuité = 1 / FRC."], }], }