Python 64.6%
TypeScript 33.7%
CSS 0.8%
1"""Template: age-life depreciation with year-by-year curve."""23from __future__ import annotations45from typing import Any67from app.tools.coerce import num, pct8910def _f(p: dict[str, Any], key: str, default: float) -> float:11 """Tolerant numeric param; keys ending in `_pct` / starting with `taux` are ratios."""12 raw = p.get(key)13 v = pct(raw, None) if (key.endswith("_pct") or key.startswith("taux")) else num(raw, None)14 return float(default) if v is None else v151617def build(p: dict[str, Any]) -> dict[str, Any]:18 cn = _f(p, "cout_neuf", 450000)19 age_eff = _f(p, "age_effectif", 12)20 dve = _f(p, "duree_vie_economique", 60)21 inputs = [22 {"cell": "B4", "label": "Coût neuf C_N ($)", "value": cn, "format": "currency",23 "name": "Cout_Neuf"},24 {"cell": "B5", "label": "Âge effectif A_e (ans)", "value": age_eff, "format": "number",25 "name": "Age_Effectif"},26 {"cell": "B6", "label": "Durée de vie économique DVE (ans)", "value": dve,27 "format": "number", "name": "DVE"},28 ]29 results = {30 "anchor": "A9",31 "columns": [{"header": "Résultat", "type": "text"}, {"header": "Valeur", "type": "currency"}],32 "rows": [33 ["Taux de dépréciation (A_e / DVE)", "=B5/B6"],34 ["Dépréciation D ($)", "=B4*B5/B6"],35 ["Coût déprécié ($)", "=B4-B11"],36 ["Durée de vie restante (ans)", "=B6-B5"],37 ],38 "row_formats": {0: "percent", 3: "number"},39 }40 years = int(min(dve, 80))41 curve_rows = [[y, f"=MIN(1,{'A'}{16 + y}/$B$6)", f"=$B$4*(1-B{16 + y})"] for y in range(0, years + 1)]42 curve = {43 "anchor": "A15",44 "columns": [{"header": "Âge (ans)", "type": "integer"},45 {"header": "Taux de dépréciation", "type": "percent"},46 {"header": "Coût déprécié ($)", "type": "currency"}],47 "rows": curve_rows,48 }49 return {50 "filename": p.get("filename", "depreciation_age_vie.xlsx"),51 "style": "uqo",52 "sheets": [{53 "name": "Âge-vie",54 "title": "Dépréciation par la méthode âge-vie",55 "inputs": inputs,56 "tables": [results, curve],57 "charts": [{"type": "line", "title": "Courbe âge-vie du coût déprécié",58 "categories_range": f"A16:A{16 + years}",59 "values_range": f"C16:C{16 + years}", "anchor": "E9"}],60 "notes": ["D = (A_e / DVE) × C_N ; la méthode suppose une dépréciation linéaire.",61 "L'âge effectif reflète l'état observé, pas l'âge chronologique."],62 }],63 }64