SPB Git forge

spb/uqo-imm1003

Public
7commits 1branches 0releases
189.5 MBsize
maindefault branch
6 h agolast push
JavaScript 68% CSS 32%
12.9 KB · 195 lines javascript
Raw Blame History
1// entrainement-imm1003.js — générateurs de problèmes à données aléatoires (IMM1003)2// Chaque générateur : { id, title, ch, url, gen(R) → { enonce, answer, unit, tol, steps } }3// R : utilitaires aléatoires fournis par app.js (R.int(a,b), R.pick(arr), R.step(a,b,step), R.money(v), R.pct(v), R.num(v,d))4window.UQO_TRAINING = [5  {6    id: "rpv", title: "RPV et mise de fonds", ch: "01", url: "/seance/01/#form-1-1",7    gen(R) {8      const prix = R.step(320000, 780000, 5000);9      const evalv = prix - R.step(0, 45000, 5000);10      const retenue = Math.min(prix, evalv);11      const pret = retenue * 0.8;12      const mise = prix - pret;13      return {14        enonce: `Une offre d’achat est acceptée à <b>${R.money(prix)}</b>. L’évaluation exigée par le prêteur conclut à <b>${R.money(evalv)}</b>. L’acheteur souhaite un prêt conventionnel (RPV maximal de 80 %). Quelle <b>mise de fonds</b> devra-t-il verser ?`,15        answer: mise, unit: "$", tol: 0.005,16        steps: `<p>1. Valeur retenue = la moindre du prix et de l’évaluation = ${R.money(retenue)}.</p><p>2. Prêt maximal = ${R.money(retenue)} × 80 % = ${R.money(pret)}.</p><p>3. Mise de fonds = prix − prêt = ${R.money(prix)} − ${R.money(pret)} = <b>${R.money(mise)}</b> (soit ${R.pct(mise / prix * 100, 1)} du prix).</p>`,17      };18    },19  },20  {21    id: "mutation", title: "Droits de mutation (barème 2026)", ch: "01", url: "/seance/01/#s-1-6-3",22    gen(R) {23      const prix = R.step(180000, 900000, 1000);24      const t1 = Math.min(prix, 62900) * 0.005;25      const t2 = Math.max(0, Math.min(prix, 315000) - 62900) * 0.01;26      const t3 = Math.max(0, prix - 315000) * 0.015;27      const tot = t1 + t2 + t3;28      return {29        enonce: `Calculez les <b>droits de mutation</b> exigibles pour une propriété acquise <b>${R.money(prix)}</b> (barème de base 2026 : 0,5 % jusqu’à 62 900 $ ; 1,0 % de 62 900 $ à 315 000 $ ; 1,5 % au-delà ; aucun taux municipal majoré).`,30        answer: tot, unit: "$", tol: 0.005,31        steps: `<p>Tranche 1 : 62 900 × 0,5 % = ${R.money2(t1)}.</p><p>Tranche 2 : ${prix > 315000 ? "(315 000 − 62 900)" : "(" + R.money(prix) + " − 62 900)"} × 1,0 % = ${R.money2(t2)}.</p>${prix > 315000 ? `<p>Tranche 3 : (${R.money(prix)} − 315 000) × 1,5 % = ${R.money2(t3)}.</p>` : "<p>Pas de tranche 3 (prix ≤ 315 000 $).</p>"}<p>Total : <b>${R.money2(tot)}</b>.</p>`,32      };33    },34  },35  {36    id: "temporel", title: "Ajustement temporel d’un comparable", ch: "08", url: "/seance/08/#s-8-4",37    gen(R) {38      const prix = R.step(300000, 700000, 1000);39      const g = R.pick([3, 4, 5, 6, 8]);40      const mois = R.int(2, 14);41      const adj = prix * g / 100 / 12 * mois;42      return {43        enonce: `Un comparable s’est vendu <b>${R.money(prix)}</b> il y a <b>${mois} mois</b>. Le marché progresse de <b>${g} % par an</b> (ajustement linéaire). Quel est le <b>prix ajusté</b> pour le temps ?`,44        answer: prix + adj, unit: "$", tol: 0.003,45        steps: `<p>Taux mensuel = ${g} % ÷ 12 = ${R.num(g / 12, 4)} %.</p><p>Ajustement = ${R.money(prix)} × ${R.num(g / 12, 4)} % × ${mois} = ${R.money(adj)} (positif : le marché a monté depuis la vente).</p><p>Prix ajusté = ${R.money(prix)} + ${R.money(adj)} = <b>${R.money(prix + adj)}</b>.</p>`,46      };47    },48  },49  {50    id: "netbrut", title: "Ajustements net et brut", ch: "09", url: "/seance/09/#s-9-4",51    gen(R) {52      const prix = R.step(350000, 650000, 5000);53      const a = [R.step(-30000, 30000, 1000), R.step(-25000, 25000, 1000), R.step(-20000, 20000, 1000), R.step(-15000, 15000, 1000)].map((x) => (x === 0 ? 5000 : x));54      const net = a.reduce((s, x) => s + x, 0);55      const brut = a.reduce((s, x) => s + Math.abs(x), 0);56      return {57        enonce: `Un comparable vendu <b>${R.money(prix)}</b> reçoit quatre ajustements : ${a.map((x) => `<b>${x > 0 ? "+" : "−"}${R.money(Math.abs(x))}</b>`).join(", ")}. Quel est l’<b>ajustement brut</b>, en pourcentage du prix de vente ? (Répondez en %, ex. 12,5)`,58        answer: brut / prix * 100, unit: "%", tol: 0.01,59        steps: `<p>Net (somme algébrique) = ${R.money(net)} → ${R.pct(net / prix * 100)} ${Math.abs(net / prix) <= 0.15 ? "(≤ 15 %, acceptable)" : "(> 15 % : fiabilité réduite)"}.</p><p>Brut (somme des valeurs absolues) = ${R.money(brut)} → <b>${R.pct(brut / prix * 100)}</b> ${brut / prix <= 0.25 ? "(≤ 25 %, acceptable)" : "(> 25 % : comparable peu fiable)"}.</p>`,60      };61    },62  },63  {64    id: "capitalisation", title: "Capitalisation directe", ch: "11", url: "/seance/11/#s-11-1",65    gen(R) {66      const rne = R.step(38000, 260000, 500);67      const tga = R.pick([4.75, 5, 5.25, 5.5, 5.75, 6, 6.25, 6.5, 7]);68      return {69        enonce: `Le revenu net d’exploitation stabilisé d’un immeuble locatif est de <b>${R.money(rne)}</b> par année. Le taux global d’actualisation extrait du marché est de <b>${R.num(tga, 2)} %</b>. Quelle est l’<b>indication de valeur</b> par capitalisation directe ?`,70        answer: rne / (tga / 100), unit: "$", tol: 0.003,71        steps: `<p>V = RNE ÷ TGA = ${R.money(rne)} ÷ ${R.num(tga, 2)} % = <b>${R.money(rne / (tga / 100))}</b>.</p><p>Vérification : ${R.money(rne / (tga / 100))} × ${R.num(tga, 2)} % ≈ ${R.money(rne)}.</p>`,72      };73    },74  },75  {76    id: "rne", title: "Du RBP au RNE", ch: "11", url: "/seance/11/#s-11-2",77    gen(R) {78      const n = R.pick([4, 6, 8, 12]);79      const loyer = R.step(850, 1650, 25);80      const inocc = R.pick([3, 4, 5]);81      const autres = R.step(0, 6000, 500);82      const ratio = R.pick([36, 38, 40, 42, 44]);83      const rbp = n * loyer * 12;84      const rbe = rbp * (1 - inocc / 100) + autres;85      const dep = rbe * ratio / 100;86      const rne = rbe - dep;87      return {88        enonce: `Un immeuble de <b>${n} logements</b> loués <b>${R.money(loyer)}</b> par mois (loyer du marché). Inoccupation et mauvaises créances : <b>${inocc} % du RBP</b> ; revenus accessoires : <b>${R.money(autres)}</b> par an ; dépenses d’exploitation : <b>${ratio} % du RBE</b>. Quel est le <b>RNE</b> ?`,89        answer: rne, unit: "$", tol: 0.003,90        steps: `<p>RBP = ${n} × ${R.money(loyer)} × 12 = ${R.money(rbp)}.</p><p>RBE = ${R.money(rbp)} × (1 − ${inocc} %) + ${R.money(autres)} = ${R.money(rbe)}.</p><p>Dépenses = ${ratio} % × ${R.money(rbe)} = ${R.money(dep)}.</p><p>RNE = ${R.money(rbe)} − ${R.money(dep)} = <b>${R.money(rne)}</b>.</p>`,91      };92    },93  },94  {95    id: "tga-extraction", title: "Extraction du TGA", ch: "12", url: "/seance/12/#s-12-2",96    gen(R) {97      const prix = R.step(600000, 3200000, 10000);98      const tga = R.pick([4.8, 5.1, 5.4, 5.6, 5.9, 6.2, 6.5]);99      const rne = Math.round(prix * tga / 100 / 10) * 10;100      return {101        enonce: `Un immeuble comparable s’est vendu <b>${R.money(prix)}</b> ; son RNE reconstruit selon les conventions du sujet est de <b>${R.money(rne)}</b>. Quel <b>TGA</b> en extrayez-vous ? (en %, deux décimales)`,102        answer: rne / prix * 100, unit: "%", tol: 0.005,103        steps: `<p>TGA = RNE ÷ prix = ${R.money(rne)} ÷ ${R.money(prix)} = <b>${R.pct(rne / prix * 100)}</b>.</p><p>MRN implicite = 1 ÷ TGA ≈ ${R.num(prix / rne, 2)}.</p>`,104      };105    },106  },107  {108    id: "bande", title: "TGA par bande d’investissement", ch: "12", url: "/seance/12/#s-12-2",109    gen(R) {110      const m = R.pick([65, 70, 75, 80]);111      const i = R.pick([4.5, 5, 5.5, 6]);112      const re = R.pick([7, 8, 9, 10]);113      const im = i / 100 / 12;114      const rm = 12 * im / (1 - Math.pow(1 + im, -300)) * 100;115      const tga = m / 100 * rm + (1 - m / 100) * re;116      return {117        enonce: `Financement type du marché : ratio prêt/valeur de <b>${m} %</b>, taux hypothécaire de <b>${R.num(i, 2)} %</b> amorti sur <b>25 ans</b> (constante hypothécaire annuelle R<sub>m</sub> = ${R.pct(rm)}), rendement exigé sur l’équité de <b>${re} %</b>. Quel est le <b>TGA</b> par bande d’investissement ? (en %)`,118        answer: tga, unit: "%", tol: 0.01,119        steps: `<p>TGA = M × R<sub>m</sub> + (1 − M) × R<sub>e</sub> = ${m} % × ${R.pct(rm)} + ${100 - m} % × ${re} %</p><p>= ${R.pct(m / 100 * rm)} + ${R.pct((1 - m / 100) * re)} = <b>${R.pct(tga)}</b>.</p>`,120      };121    },122  },123  {124    id: "mrb", title: "Multiplicateur de revenu brut", ch: "12", url: "/seance/12/#s-12-5",125    gen(R) {126      const rbe = R.step(60000, 420000, 1000);127      const mrb = R.pick([8.5, 9, 9.5, 10, 10.5, 11]);128      return {129        enonce: `Les ventes récentes d’immeubles semblables affichent un MRB de <b>${R.num(mrb, 1)}</b>. Le sujet a un RBE de <b>${R.money(rbe)}</b>. Quelle <b>indication de valeur</b> le multiplicateur donne-t-il ?`,130        answer: rbe * mrb, unit: "$", tol: 0.003,131        steps: `<p>V = RBE × MRB = ${R.money(rbe)} × ${R.num(mrb, 1)} = <b>${R.money(rbe * mrb)}</b>.</p><p>Rappel : le MRB est un filtre rapide, aveugle aux dépenses ; il ne remplace pas la capitalisation du RNE.</p>`,132      };133    },134  },135  {136    id: "reversion", title: "Valeur de réversion (DCF)", ch: "12", url: "/seance/12/#s-12-3",137    gen(R) {138      const rne = R.step(90000, 400000, 1000);139      const tgaout = R.pick([5.5, 5.75, 6, 6.25, 6.5]);140      const frais = R.pick([2, 2.5, 3, 4]);141      const brute = rne / (tgaout / 100);142      return {143        enonce: `À la fin d’une détention de 5 ans, le RNE de l’<b>année 6</b> est projeté à <b>${R.money(rne)}</b>. TGA de sortie : <b>${R.num(tgaout, 2)} %</b> ; frais de vente : <b>${R.num(frais, 1)} %</b> de la valeur brute. Quelle est la <b>valeur de réversion nette</b> ?`,144        answer: brute * (1 - frais / 100), unit: "$", tol: 0.003,145        steps: `<p>Valeur brute = RNE<sub>6</sub> ÷ TGA<sub>sortie</sub> = ${R.money(rne)} ÷ ${R.num(tgaout, 2)} % = ${R.money(brute)}.</p><p>Frais de vente = ${R.num(frais, 1)} % × ${R.money(brute)} = ${R.money(brute * frais / 100)}.</p><p>Réversion nette = <b>${R.money(brute * (1 - frais / 100))}</b>.</p>`,146      };147    },148  },149  {150    id: "va", title: "Valeur présente d’un flux", ch: "12", url: "/seance/12/#s-12-3",151    gen(R) {152      const fv = R.step(100000, 2500000, 5000);153      const r = R.pick([6, 6.5, 7, 7.5, 8, 9]);154      const n = R.int(3, 10);155      const pv = fv / Math.pow(1 + r / 100, n);156      return {157        enonce: `Quelle est la <b>valeur présente</b> de <b>${R.money(fv)}</b> reçus dans <b>${n} ans</b>, actualisés à <b>${R.num(r, 1)} %</b> ?`,158        answer: pv, unit: "$", tol: 0.003,159        steps: `<p>PV = FV ÷ (1 + r)<sup>n</sup> = ${R.money(fv)} ÷ (1,${String(r * 10).padStart(3, "0")})<sup>${n}</sup> = ${R.money(fv)} ÷ ${R.num(Math.pow(1 + r / 100, n), 4)} = <b>${R.money(pv)}</b>.</p>`,160      };161    },162  },163  {164    id: "cout-agevie", title: "Méthode du coût — âge/vie modifiée", ch: "10", url: "/seance/10/#s-10-3",165    gen(R) {166      const cneuf = R.step(380000, 900000, 5000);167      const cur = R.step(5000, 30000, 500);168      const age = R.int(8, 35);169      const vie = R.pick([50, 55, 60, 65]);170      const terrain = R.step(90000, 260000, 5000);171      const inc = (cneuf - cur) * age / vie;172      const val = cneuf - cur - inc + terrain;173      return {174        enonce: `Coût de remplacement à neuf : <b>${R.money(cneuf)}</b> ; entretien différé (curable) : <b>${R.money(cur)}</b> ; âge effectif : <b>${age} ans</b> ; vie utile économique : <b>${vie} ans</b> ; valeur du terrain : <b>${R.money(terrain)}</b>. Aucune dépréciation fonctionnelle ni économique. Quelle est la <b>valeur</b> par la méthode du coût (âge/vie modifiée) ?`,175        answer: val, unit: "$", tol: 0.003,176        steps: `<p>Base résiduelle = ${R.money(cneuf)} − ${R.money(cur)} = ${R.money(cneuf - cur)}.</p><p>Physique incurable = ${R.money(cneuf - cur)} × ${age}/${vie} = ${R.money(inc)}.</p><p>Valeur dépréciée des améliorations = ${R.money(cneuf)} − ${R.money(cur)} − ${R.money(inc)} = ${R.money(cneuf - cur - inc)}.</p><p>V = ${R.money(cneuf - cur - inc)} + ${R.money(terrain)} = <b>${R.money(val)}</b>.</p>`,177      };178    },179  },180  {181    id: "reconciliation", title: "Réconciliation pondérée", ch: "14", url: "/seance/14/#s-14-6",182    gen(R) {183      const base = R.step(400000, 2000000, 10000);184      const vc = base, vk = base + R.step(-60000, 60000, 5000), vr = base + R.step(-50000, 50000, 5000);185      const w = R.pick([[50, 20, 30], [40, 15, 45], [60, 10, 30], [35, 25, 40], [45, 20, 35]]);186      const val = (vc * w[0] + vk * w[1] + vr * w[2]) / 100;187      return {188        enonce: `Indications : comparaison <b>${R.money(vc)}</b> (poids ${w[0]} %), coût <b>${R.money(vk)}</b> (poids ${w[1]} %), revenu <b>${R.money(vr)}</b> (poids ${w[2]} %). Quelle est la <b>valeur pondérée</b> (avant arrondi) ?`,189        answer: val, unit: "$", tol: 0.002,190        steps: `<p>V = ${R.money(vc)} × ${w[0]} % + ${R.money(vk)} × ${w[1]} % + ${R.money(vr)} × ${w[2]} %</p><p>= ${R.money(vc * w[0] / 100)} + ${R.money(vk * w[1] / 100)} + ${R.money(vr * w[2] / 100)} = <b>${R.money(val)}</b> (à arrondir au 5 000 $ : ${R.money(Math.round(val / 5000) * 5000)}).</p>`,191      };192    },193  },194];195