SPB Git
3.5 KB · 61 lines python
1#!/usr/bin/env python32"""Figure ch24 — décomposition de la valeur par le coût du sujet du cas 1 (DONNÉES SYNTHÉTIQUES, graine 20261031) :3(a) lecture ventilée (ch. 11) : coût neuf − curable − courte durée − longue durée − désuétude fonctionnelle ;4(b) lecture retenue : coût neuf − dépréciation extraite du marché − désuétude fonctionnelle + valeur du terrain = indication.5Sortie : assets/figures/ch24/ch24-fig-decomposition.pdf"""6import sys, pathlib7ROOT = pathlib.Path(__file__).resolve().parents[3]8sys.path.insert(0, str(ROOT / "analysis/python")); sys.path.insert(0, str(ROOT / "analysis/python/cases"))9import matplotlib.pyplot as plt10from traite.style import setup, palette, savefig, LARGEUR, fmt_dollars1112esc = lambda t: t.replace("$", r"\$")13import ch24_depreciation as cas141516def cascade(ax, etapes, titre):17    """etapes : liste de (nom, montant, type) avec type ∈ {'total', 'moins', 'plus', 'resultat'}."""18    cum = 0.0; xs = []; 19    for i, (nom, m, t) in enumerate(etapes):20        if t == "total":21            ax.bar(i, m, color=palette.cat[0], width=0.62); cum = m; top = m22        elif t == "moins":23            ax.bar(i, -m, bottom=cum, color=palette.cat[1], width=0.62); cum -= m; top = cum + m24        elif t == "plus":25            ax.bar(i, m, bottom=cum, color=palette.cat[2], width=0.62); cum += m; top = cum26        else:27            ax.bar(i, m, color=palette.cat[4], width=0.62); top = m28        signe = "−" if t == "moins" else ("+" if t == "plus" else "")29        ax.text(i, top + 9000, esc(f"{signe}{fmt_dollars(m)}"), ha="center", va="bottom", fontsize=7, color=palette.ink)30        xs.append(nom)31        if i < len(etapes) - 1 and t != "resultat":32            ax.plot([i + 0.31, i + 1 - 0.31], [cum, cum], color=palette.ink2, lw=0.6)33    ax.set_xticks(range(len(etapes))); ax.set_xticklabels(xs, fontsize=7.5, rotation=0)34    ax.yaxis.set_major_formatter(plt.FuncFormatter(fmt_dollars))35    ax.set_ylim(0, 760000); ax.grid(axis="x", visible=False)36    ax.set_title(esc(titre), loc="left", fontsize=9)373839def main():40    setup()41    d = cas.charger()42    var = cas.variantes_physique(d["cn"], d["fiche"], d["travaux"])43    se = cas.carence_salle_eau(d["devis"], d["cn"])44    w, vl = cas.extraction(d["ventes"], d["modele"], d["cn"]["total"])45    q = cas.ajuster_profil(w)["quadratique"]; vlr = cas.valeur_terrain_retenue(vl)46    vs = cas.valeur_sujet(d["cn"], vlr["retenue"], q, se["desuetude"], var)47    ve = var["ventilee"]; cn = d["cn"]["total"]48    fig, (a, b) = plt.subplots(2, 1, figsize=(LARGEUR, 5.6), gridspec_kw={"hspace": 0.42})49    cascade(a, [("Coût neuf", cn, "total"), ("Curable", ve["curable"], "moins"), ("Courte durée", sum(ve["courte_duree"].values()), "moins"),50                ("Longue durée", ve["longue_duree"], "moins"), ("Fonctionnelle", se["desuetude"], "moins"),51                ("Contribution\ndu bâtiment", vs["A_ventilee"]["contribution_batiment"], "resultat")],52            f"(a) Lecture ventilée : dépréciation totale {vs['A_ventilee']['taux_depreciation']*100:.1f} %")53    cascade(b, [("Coût neuf", cn, "total"), ("Extraite (28 ans)", vs["d_extraite"], "moins"), ("Fonctionnelle", se["desuetude"], "moins"),54                ("Terrain", vlr["retenue"], "plus"), ("Indication\npar le coût", vs["B_extraction"]["valeur"], "resultat")],55            f"(b) Lecture retenue : dépréciation {vs['B_extraction']['taux_depreciation']*100:.1f} %, valeur {fmt_dollars(vs['valeur_arrondie'])}")56    out = savefig(fig, "ch24/ch24-fig-decomposition.pdf"); print("OK", out)575859if __name__ == "__main__":60    main()61
Files · 4958fcec3502ce9b6da151998f7eaebf95b47bcc
Menu

Theme