SPB Git

Repository Public Research preview

Commit

chore: chemins mis à jour après la réorganisation du Bureau (2026-11-01)

UQO/ est désormais structuré en Enseignement, Recherche, Administration, Supervision ; Recherche-UQO vit dans UQO/Recherche/.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed · Nov 1, 2026 parent 0dbbbd1
17 changed files +268 −25 Browse files
17 changed files
modified IMM1003-20_Elements_evaluation_immobiliere/03_Travaux_pratiques/TP1_Tableau_de_bord_du_marche/retroaction_etudiants/Bissonnette_David/courriel_Bissonnette_David.md +2 −2
@@ -1,8 +1,8 @@
1 1 **À :** David Bissonnette
2 2 **Objet :** IMM1003-20 — TP1 corrigé : votre note, la grille de correction et votre classeur annoté
3 3 **Pièces jointes :**
4 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_BISD28318805_grille_correction.pdf`
5 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_BISD28318805_corrige_SPB.xlsx`
4 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_BISD28318805_grille_correction.pdf`
5 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_BISD28318805_corrige_SPB.xlsx`
6 6
7 7 Bonjour Monsieur Bissonnette,
8 8
modified IMM1003-20_Elements_evaluation_immobiliere/03_Travaux_pratiques/TP1_Tableau_de_bord_du_marche/retroaction_etudiants/Richer_Caroline/courriel_Richer_Caroline.md +2 −2
@@ -1,8 +1,8 @@
1 1 **À :** Caroline Richer
2 2 **Objet :** IMM1003-20 — TP1 corrigé : votre note, la grille de correction et votre classeur annoté
3 3 **Pièces jointes :**
4 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_RICC05286804_grille_correction.pdf`
5 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_RICC05286804_corrige_SPB.xlsx`
4 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_RICC05286804_grille_correction.pdf`
5 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_RICC05286804_corrige_SPB.xlsx`
6 6
7 7 Bonjour Madame Richer,
8 8
modified IMM1003-20_Elements_evaluation_immobiliere/03_Travaux_pratiques/TP1_Tableau_de_bord_du_marche/retroaction_etudiants/Tessier-Proulx_Marieve/courriel_Tessier-Proulx_Marieve.md +2 −2
@@ -1,8 +1,8 @@
1 1 **À :** Mariève Tessier-Proulx
2 2 **Objet :** IMM1003-20 — TP1 corrigé : votre note, la grille de correction et votre classeur annoté
3 3 **Pièces jointes :**
4 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_TESM78290105_grille_correction.pdf`
5 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_TESM78290105_corrige_SPB.xlsx`
4 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_TESM78290105_grille_correction.pdf`
5 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_TESM78290105_corrige_SPB.xlsx`
6 6
7 7 Bonjour Madame Tessier-Proulx,
8 8
added IMM1003-20_Elements_evaluation_immobiliere/04_Examens/Intra_30pct/correction/_outils/make_correction_intra.py +243 −0
@@ -0,0 +1,243 @@
1 +# -*- coding: utf-8 -*-
2 +"""Grilles de correction de l'examen de mi-session IMM1003-20 (examen maison 72 h, 19 questions, 100 pts, 30 %).
3 +Pour chaque copie du dict COPIES (fichier copies_intra_*.py) : une grille PDF (HTML + WeasyPrint), un courriel .md,
4 +une ligne dans notes_intra_IMM1003.csv.
5 +Usage : python3 -I make_correction_intra.py copies_intra_20261029 [CLE ...]
6 +Sorties : INTRA_OUT (défaut ~/Desktop/UQO/Enseignement/corrections/examen-intra-imm1003/correction) + copie dans ../copies/.
7 +"""
8 +import html, os, sys, csv, subprocess, importlib, shutil
9 +
10 +HERE = os.path.dirname(os.path.abspath(__file__))
11 +sys.path.insert(0, HERE)
12 +OUT = os.environ.get("INTRA_OUT", os.path.expanduser("~/Desktop/UQO/Enseignement/corrections/examen-intra-imm1003/correction"))
13 +MIRROR = os.path.join(os.path.dirname(HERE), "copies")
14 +os.makedirs(OUT, exist_ok=True); os.makedirs(MIRROR, exist_ok=True); os.makedirs("/tmp/corr", exist_ok=True)
15 +
16 +PARTIES = {"A": "Lire le marché de Gatineau dans nos ventes réelles", "B": "Valeur, prix, coût et rôle : le 505, rue Nadon",
17 + "C": "Les municipalités voisines et les principes", "D": "Collecte, validation et sélection des données",
18 + "E": "Cadre professionnel et déontologie"}
19 +PARTIE_DE = {1: "A", 2: "A", 3: "A", 4: "A", 5: "B", 6: "B", 7: "B", 8: "B", 9: "C", 10: "C", 11: "C",
20 + 12: "D", 13: "D", 14: "D", 15: "D", 16: "E", 17: "E", 18: "E", 19: "E"}
21 +TITRES = {1: "Douze mois de marché", 2: "Moyenne, médiane et la maison du chemin d'Aylmer", 3: "La phase du cycle",
22 + 4: "Gatineau face au Québec", 5: "Ce que la revente dit — et ne dit pas", 6: "Le rôle n'est pas le marché",
23 + 7: "Lire une distribution de ratios", 8: "Prix, valeur, coût : quatre mandats", 9: "Chelsea coûte 59 % de plus",
24 + 10: "Des ratios qu'on ne peut pas comparer", 11: "L'utilisation optimale d'une petite maison neuve",
25 + 12: "Validation d'un extrait brut", 13: "Choisir ses comparables", 14: "Confirmer une vente",
26 + 15: "Les limites de nos données", 16: "Le courtier ou l'évaluateur agréé ?", 17: "Le boni du chemin d'Aylmer",
27 + 18: "Une erreur et ses conséquences", 19: "L'estimation n'est pas l'évaluation"}
28 +MAX = {1: 6, 2: 5, 3: 5, 4: 6, 5: 5, 6: 5, 7: 5, 8: 5, 9: 6, 10: 5, 11: 7, 12: 8, 13: 8, 14: 4, 15: 4, 16: 4, 17: 4, 18: 4, 19: 4}
29 +
30 +# Valeurs de référence du solutionnaire (affichées dans la grille)
31 +REF = [("Q1", "−25,2 % ventes · +5,3 % médiane · saisonnalité 2,14"),
32 + ("Q2", "465 452 $ (écart ≈ 13 600 $) · vente légitime (ratio prix/rôle 0,96)"),
33 + ("Q4", "Gatineau 122,2 / 128,0 / 132,2 · Québec 124,9 / 136,6 / 148,8"),
34 + ("Q5", "+25,0 % → 4,6 %/an (TCAC) · marché +32,2 % → 5,7 %/an"),
35 + ("Q6", "1,775 / 1,237 · références 1er juillet 2019 et 1er juillet 2022 (art. 46), valeur réelle (art. 43)"),
36 + ("Q7", "1,237 entre P75 (1,180) et P90 (1,271) ≈ 85e centile"),
37 + ("Q9", "1,585 / 1,154 / 8,7 · taille ≈ +37 % (1,585 ÷ 1,154)"),
38 + ("Q13", "no 7 obligatoire · médiane ≈ 4 277 $/m² → ≈ 480 000 $ (470 000–520 000) · prix payé ≈ +20 %")]
39 +
40 +
41 +def Q(num, items, note=None):
42 + mx = sum(i[1] for i in items)
43 + assert abs(mx - MAX[num]) < 1e-9, f"Q{num}: barème {mx} ≠ {MAX[num]}"
44 + return {"num": num, "titre": TITRES[num], "items": items, "note": note, "max": mx, "got": sum(i[2] for i in items)}
45 +
46 +
47 +def fr(x):
48 + if abs(x - round(x)) < 1e-9: return str(int(round(x)))
49 + return ("%.2f" % x).rstrip("0").rstrip(".").replace(".", ",")
50 +
51 +
52 +def appreciation(n):
53 + if n >= 90: return "Excellent"
54 + if n >= 80: return "Très bien"
55 + if n >= 70: return "Bien"
56 + if n >= 60: return "Passable"
57 + return "Insuffisant"
58 +
59 +
60 +E = html.escape
61 +CSS = """
62 +@page { size: A4; margin: 17mm 15mm 18mm 15mm;
63 + @bottom-left { content: "UQO · IMM1003-20 · Examen de mi-session · Grille de correction"; font: 8pt 'Avenir Next', Helvetica; color:#58595B; }
64 + @bottom-right { content: "Page " counter(page) " / " counter(pages); font: 8pt 'Avenir Next', Helvetica; color:#58595B; } }
65 +* { box-sizing: border-box; }
66 +body { font-family: 'Avenir Next', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 9.6pt; color: #1d1d1f; line-height: 1.38; }
67 +h1,h2,h3 { margin: 0; }
68 +.band { background: #003E7E; color: #fff; padding: 11px 16px; border-radius: 6px; display: flex; justify-content: space-between; align-items: center; }
69 +.band .u { font-size: 8.5pt; letter-spacing: .04em; text-transform: uppercase; opacity: .85; }
70 +.band h1 { font-size: 17pt; font-weight: 700; margin-top: 2px; }
71 +.band .right { text-align: right; font-size: 9pt; line-height: 1.3; }
72 +.ident { display: flex; gap: 12px; margin-top: 12px; }
73 +.ident .box { flex: 1; background: #F0F4F8; border-radius: 6px; padding: 9px 12px; }
74 +.ident .box table { width: 100%; border-collapse: collapse; }
75 +.ident .box td { padding: 2px 0; vertical-align: top; }
76 +.ident .box td.k { color: #58595B; width: 34%; font-size: 8.6pt; text-transform: uppercase; letter-spacing: .03em; }
77 +.score { width: 190px; background: #008046; color: #fff; border-radius: 6px; padding: 10px 12px; text-align: center; display:flex; flex-direction:column; justify-content:center; }
78 +.score.mid { background: #C6A300; } .score.low { background: #B42318; }
79 +.score .big { font-size: 30pt; font-weight: 700; line-height: 1; }
80 +.score .big small { font-size: 13pt; font-weight: 500; }
81 +.score .app { font-size: 11pt; font-weight: 600; margin-top: 4px; }
82 +.score .pond { font-size: 8.5pt; opacity: .9; margin-top: 3px; }
83 +h2 { font-size: 12.5pt; color: #003E7E; border-bottom: 2px solid #0066B3; padding-bottom: 3px; margin: 16px 0 8px; }
84 +h2 .pts { float: right; font-size: 10.5pt; color: #fff; background: #0066B3; border-radius: 10px; padding: 1px 10px; font-weight: 600; }
85 +h2 .pts.low { background: #B42318; } h2 .pts.mid { background: #C6A300; } h2 .pts.full { background: #008046; }
86 +h3.partie { font-size: 10.5pt; color: #fff; background: #0066B3; padding: 4px 10px; border-radius: 4px; margin: 14px 0 4px; }
87 +table.grid { width: 100%; border-collapse: collapse; margin-top: 4px; }
88 +table.grid th { background: #003E7E; color: #fff; font-weight: 600; font-size: 8.6pt; text-align: left; padding: 5px 7px; }
89 +table.grid td { padding: 5px 7px; border-bottom: 1px solid #d9e1ea; vertical-align: top; }
90 +table.grid tr:nth-child(even) td { background: #F7F9FC; }
91 +table.grid td.num { text-align: center; white-space: nowrap; font-variant-numeric: tabular-nums; }
92 +table.grid td.c { font-weight: 600; }
93 +table.grid tr.part td { background: #E8EEF5; font-weight: 600; color: #003E7E; }
94 +.bar { height: 7px; background: #e3e8ee; border-radius: 4px; overflow: hidden; width: 110px; display: inline-block; vertical-align: middle; margin-left: 6px; }
95 +.bar i { display: block; height: 100%; background: #008046; }
96 +.bar i.mid { background: #C6A300; } .bar i.low { background: #B42318; }
97 +.note { background: #FFF6D5; border-left: 4px solid #C6A300; padding: 6px 10px; margin: 6px 0 2px; font-size: 9.2pt; border-radius: 0 4px 4px 0; }
98 +.two { display: flex; gap: 12px; }
99 +.two > div { flex: 1; }
100 +.card { border: 1px solid #d9e1ea; border-radius: 6px; padding: 8px 12px; }
101 +.card h3 { font-size: 10.5pt; margin-bottom: 4px; }
102 +.card.plus h3 { color: #008046; } .card.minus h3 { color: #B42318; }
103 +ul { margin: 2px 0 2px 16px; padding: 0; } li { margin: 2px 0; }
104 +.resume { background: #F0F4F8; border-radius: 6px; padding: 9px 12px; margin-top: 10px; font-size: 9.8pt; }
105 +.legend { font-size: 8.6pt; color: #58595B; margin-top: 6px; }
106 +.small { font-size: 8.6pt; color: #58595B; }
107 +.pb { page-break-before: always; }
108 +.sig { margin-top: 18px; display:flex; justify-content: space-between; font-size: 9pt; color:#58595B; }
109 +"""
110 +
111 +
112 +def build_html(S, total):
113 + tot_max = sum(q["max"] for q in S["questions"])
114 + assert tot_max == 100
115 + def cls(got, mx):
116 + r = got / mx if mx else 1
117 + return "full" if r >= 0.999 else ("low" if r < 0.6 else "mid")
118 + def barcls(got, mx):
119 + r = got / mx if mx else 1
120 + return "" if r >= 0.85 else ("low" if r < 0.6 else "mid")
121 + scorecls = "" if total >= 80 else ("low" if total < 60 else "mid")
122 + h = [f"<html><head><meta charset='utf-8'><style>{CSS}</style></head><body>"]
123 + h.append(f"""
124 +<div class="band">
125 + <div><div class="u">Université du Québec en Outaouais · Département des sciences administratives</div>
126 + <h1>Grille de correction — Examen de mi-session</h1>
127 + <div class="u">IMM1003-20 · Éléments d'évaluation immobilière · Automne 2026</div></div>
128 + <div class="right">Examen maison individuel (72 h)<br>19 questions · 5 parties · 100 points · 30 % de la note finale<br>Données réelles d'UQO Éval (6 octobre 2026)</div>
129 +</div>
130 +<div class="ident">
131 + <div class="box"><table>
132 + <tr><td class="k">Étudiant·e</td><td><b>{E(S['nom'])}</b></td></tr>
133 + <tr><td class="k">Code permanent</td><td>{S['code']}</td></tr>
134 + <tr><td class="k">Remise</td><td>{E(S['remise'])}</td></tr>
135 + <tr><td class="k">Déclarations</td><td>{E(S['declarations'])}</td></tr>
136 + <tr><td class="k">Correction</td><td>Simon-Pierre Boucher · {E(S['date_corr'])}</td></tr>
137 + </table></div>
138 + <div class="score {scorecls}"><div class="big">{fr(total)}<small> / 100</small></div>
139 + <div class="app">{appreciation(total)}</div>
140 + <div class="pond">Pondération 30 % → {fr(round(total * 0.3, 2))} / 30</div></div>
141 +</div>
142 +<div class="resume"><b>En résumé.</b> {E(S['resume'])}</div>
143 +""")
144 + h.append("<h2>Récapitulatif par question</h2><table class='grid'><tr><th style='width:34px'>Q</th><th>Objet évalué</th><th style='width:56px'>Points</th><th style='width:56px'>Obtenu</th><th style='width:150px'>Progression</th></tr>")
145 + cur = None
146 + for q in S["questions"]:
147 + p = PARTIE_DE[q["num"]]
148 + if p != cur:
149 + cur = p
150 + pm = sum(x["max"] for x in S["questions"] if PARTIE_DE[x["num"]] == p)
151 + pg = sum(x["got"] for x in S["questions"] if PARTIE_DE[x["num"]] == p)
152 + h.append(f"<tr class='part'><td class='num'>{p}</td><td>{E(PARTIES[p])}</td><td class='num'>{fr(pm)}</td><td class='num'>{fr(pg)}</td><td class='num'>{fr(round(pg/pm*100))} %</td></tr>")
153 + r = q["got"] / q["max"]
154 + h.append(f"<tr><td class='num c'>{q['num']}</td><td>{E(q['titre'])}</td><td class='num'>{fr(q['max'])}</td><td class='num c'>{fr(q['got'])}</td>"
155 + f"<td class='num'>{fr(round(r*100))} %<span class='bar'><i class='{barcls(q['got'],q['max'])}' style='width:{r*100:.0f}%'></i></span></td></tr>")
156 + h.append(f"<tr><td></td><td class='c'>Total</td><td class='num c'>100</td><td class='num c'>{fr(total)}</td><td class='num c'>{fr(round(total))} %</td></tr></table>")
157 + h.append("<div class='two' style='margin-top:12px'><div class='card plus'><h3>Points forts</h3><ul>" + "".join(f"<li>{E(x)}</li>" for x in S["forces"]) +
158 + "</ul></div><div class='card minus'><h3>À améliorer</h3><ul>" + "".join(f"<li>{E(x)}</li>" for x in S["ameliorer"]) + "</ul></div></div>")
159 + h.append("<h2>Vos résultats et la solution de référence</h2><table class='grid'><tr><th style='width:40px'>Q</th><th>Votre copie</th><th>Référence du cours (solutionnaire)</th></tr>")
160 + for (k, ref), mine in zip(REF, S["cles"]):
161 + h.append(f"<tr><td class='c'>{k}</td><td>{E(mine)}</td><td>{E(ref)}</td></tr>")
162 + h.append("</table>")
163 + h.append("<h2 style='margin-top:18px'>Détail de la correction, question par question</h2>")
164 + cur = None
165 + for q in S["questions"]:
166 + p = PARTIE_DE[q["num"]]
167 + if p != cur:
168 + cur = p
169 + h.append(f"<h3 class='partie'>Partie {p} — {E(PARTIES[p])}</h3>")
170 + h.append(f"<h2>Question {q['num']} — {E(q['titre'])}<span class='pts {cls(q['got'],q['max'])}'>{fr(q['got'])} / {fr(q['max'])}</span></h2>")
171 + h.append("<table class='grid'><tr><th style='width:30%'>Critère (grille de correction)</th><th style='width:40px'>Max</th><th style='width:52px'>Obtenu</th><th>Observations</th></tr>")
172 + for lab, mx, got, com in q["items"]:
173 + h.append(f"<tr><td>{E(lab)}</td><td class='num'>{fr(mx)}</td><td class='num c'>{fr(got)}</td><td>{E(com)}</td></tr>")
174 + h.append("</table>")
175 + if q["note"]:
176 + h.append(f"<div class='note'>{E(q['note'])}</div>")
177 + h.append("<div class='legend' style='margin-top:12px'><b>Règles appliquées</b> (grille de correction de l'examen) : démarche = formule + substitution + résultat + interprétation ; "
178 + "erreur d'arithmétique isolée : −0,5 au plus ; erreur reportée pénalisée une seule fois ; interprétation sans donnée précise du questionnaire : au plus 50 % de l'item ; "
179 + "tolérances ±0,1 point de % sur les variations, ±0,003 sur les ratios, ±50 $ sur les montants ; l'usage déclaré d'outils d'IA n'est jamais pénalisé en soi ; "
180 + "le format de la remise (PDF, classeur Excel, copie manuscrite) n'est pas noté.</div>")
181 + h.append(f"<div class='sig'><span>Note finale : <b>{fr(total)} / 100</b> ({appreciation(total)}) — saisie Moodle : {fr(round(total * 0.3, 2))} / 30</span><span>Simon-Pierre Boucher, professeur · {E(S['date_corr'])}</span></div>")
182 + h.append("</body></html>")
183 + return "\n".join(h)
184 +
185 +
186 +def courriel(S, total):
187 + prenom = S["nom"].split(",")[1].strip() if "," in S["nom"] else S["nom"].split()[0]
188 + lines = [f"**À :** {S.get('courriel', '')} ", f"**Objet :** IMM1003-20 — Examen de mi-session : votre note et la grille de correction", "",
189 + f"Bonjour {prenom},", "",
190 + f"Votre examen de mi-session est corrigé : **{fr(total)} / 100** ({appreciation(total)}), soit {fr(round(total*0.3,2))} / 30 dans la note finale. "
191 + f"La grille de correction détaillée est en pièce jointe ({S['out_base']}_grille_correction.pdf) : barème par question, points obtenus et observations.", "",
192 + "**En résumé.** " + S["resume"], "", "**Points forts**", ""] + [f"- {x}" for x in S["forces"]] + ["", "**À travailler pour l'examen final**", ""] + [f"- {x}" for x in S["ameliorer"]]
193 + if S.get("courriel_note"):
194 + lines += ["", S["courriel_note"]]
195 + lines += ["", "N'hésitez pas à passer me voir ou à m'écrire pour revoir une question avec vous.", "", "Simon-Pierre Boucher ", "Professeur, IMM1003-20"]
196 + return "\n".join(lines)
197 +
198 +
199 +def run(S):
200 + total = round(sum(q["got"] for q in S["questions"]) * 4) / 4
201 + S["total"] = total
202 + base = S["out_base"]
203 + html_path = f"/tmp/corr/{base}_grille.html"
204 + pdf_path = os.path.join(OUT, f"{base}_grille_correction.pdf")
205 + open(html_path, "w", encoding="utf-8").write(build_html(S, total))
206 + subprocess.run(["/opt/homebrew/bin/weasyprint", html_path, pdf_path], check=True)
207 + slug = S["nom"].replace(", ", "_").replace(" ", "_").replace("'", "")
208 + md_path = os.path.join(OUT, f"courriel_{slug}.md")
209 + open(md_path, "w", encoding="utf-8").write(courriel(S, total))
210 + for p in (pdf_path, md_path):
211 + shutil.copy2(p, MIRROR)
212 + print(f"{S['nom']} ({S['code']}) : {fr(total)} / 100 → {pdf_path}")
213 + return total
214 +
215 +
216 +def registry(rows):
217 + path = os.path.join(OUT, "notes_intra_IMM1003.csv")
218 + existing = {}
219 + if os.path.exists(path):
220 + with open(path, encoding="utf-8") as f:
221 + for r in csv.DictReader(f):
222 + existing[r["code"]] = r
223 + for r in rows:
224 + existing[r["code"]] = r
225 + cols = ["code", "nom", "note_100", "note_30", "appreciation", "date_correction", "remise", "declarations"]
226 + with open(path, "w", encoding="utf-8", newline="") as f:
227 + w = csv.DictWriter(f, fieldnames=cols); w.writeheader()
228 + for k in sorted(existing, key=lambda c: existing[c]["nom"]):
229 + w.writerow({c: existing[k].get(c, "") for c in cols})
230 + shutil.copy2(path, MIRROR)
231 + print("registre :", path)
232 +
233 +
234 +if __name__ == "__main__":
235 + mod = importlib.import_module(sys.argv[1])
236 + keys = sys.argv[2:] or list(mod.COPIES)
237 + rows = []
238 + for k in keys:
239 + S = mod.COPIES[k]
240 + t = run(S)
241 + rows.append({"code": S["code"], "nom": S["nom"], "note_100": fr(t), "note_30": fr(round(t * 0.3, 2)), "appreciation": appreciation(t),
242 + "date_correction": S["date_corr"], "remise": S["remise"], "declarations": S["declarations"]})
243 + registry(rows)
modified IMM1003-20_Elements_evaluation_immobiliere/05_Ressources/scripts_gabarits_excel/make_IMM1003_TP2.py +1 −1
@@ -26,7 +26,7 @@ from uqo_xlsx import (
26 26 table, titre_section, zone_texte,
27 27 )
28 28
29 −OUT = "/Users/simon-pierreboucher/Desktop/UQO/UQO_PREPARATION_COURS/output/IMM1003-20/TP2/IMM1003-20_TP2_gabarit.xlsx"
29 +OUT = "/Users/simon-pierreboucher/Desktop/UQO/Enseignement/UQO_PREPARATION_COURS/output/IMM1003-20/TP2/IMM1003-20_TP2_gabarit.xlsx"
30 30 FMT_D = '#,##0" $"'
31 31 FMT_P1 = "0.0%"
32 32
modified IMM1003-20_Elements_evaluation_immobiliere/05_Ressources/scripts_gabarits_excel/make_IMM1003_TP3.py +1 −1
@@ -26,7 +26,7 @@ from uqo_xlsx import (
26 26 table, titre_section, zone_texte,
27 27 )
28 28
29 −OUT = "/Users/simon-pierreboucher/Desktop/UQO/UQO_PREPARATION_COURS/output/IMM1003-20/TP3/IMM1003-20_TP3_gabarit.xlsx"
29 +OUT = "/Users/simon-pierreboucher/Desktop/UQO/Enseignement/UQO_PREPARATION_COURS/output/IMM1003-20/TP3/IMM1003-20_TP3_gabarit.xlsx"
30 30 FMT_D = '#,##0" $"'
31 31 FMT_P1 = "0.0%"
32 32 FMT_P2 = "0.00%"
modified IMM1033-20_Methodes_du_cout/03_Travaux_pratiques/TP1_Evaluation_d_un_terrain/retroaction_etudiants/Aubut_Bergeron_Olivier/courriel_Aubut_Bergeron_Olivier.md +2 −2
@@ -1,8 +1,8 @@
1 1 **À :** Olivier Aubut Bergeron
2 2 **Objet :** IMM1033-20 — TP1 corrigé : votre note, la grille de correction et votre classeur annoté
3 3 **Pièces jointes :**
4 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_AUBO04088109_grille_correction.pdf`
5 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_AUBO04088109_corrige_SPB.xlsx`
4 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_AUBO04088109_grille_correction.pdf`
5 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_AUBO04088109_corrige_SPB.xlsx`
6 6
7 7 Bonjour Monsieur Aubut Bergeron,
8 8
modified IMM1033-20_Methodes_du_cout/03_Travaux_pratiques/TP1_Evaluation_d_un_terrain/retroaction_etudiants/Besbes_Sarah/courriel_Besbes_Sarah.md +2 −2
@@ -1,8 +1,8 @@
1 1 **À :** Sarah Besbes
2 2 **Objet :** IMM1033-20 — TP1 corrigé : 85 / 100, grille de correction et classeur annoté
3 3 **Pièces jointes :**
4 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_BESS76660205_grille_correction.pdf`
5 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_BESS76660205_corrige_SPB.xlsx`
4 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_BESS76660205_grille_correction.pdf`
5 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_BESS76660205_corrige_SPB.xlsx`
6 6
7 7 Bonjour Madame Besbes,
8 8
modified IMM1033-20_Methodes_du_cout/03_Travaux_pratiques/TP1_Evaluation_d_un_terrain/retroaction_etudiants/Couture_Nancy/courriel_Couture_Nancy.md +2 −2
@@ -1,8 +1,8 @@
1 1 **À :** Nancy Couture
2 2 **Objet :** IMM1033-20 — TP1 corrigé : votre note, la grille de correction et votre classeur annoté
3 3 **Pièces jointes :**
4 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_COUN25268204_grille_correction.pdf`
5 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_COUN25268204_corrige_SPB.xlsx`
4 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_COUN25268204_grille_correction.pdf`
5 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_COUN25268204_corrige_SPB.xlsx`
6 6
7 7 Bonjour Madame Couture,
8 8
modified IMM1033-20_Methodes_du_cout/03_Travaux_pratiques/TP1_Evaluation_d_un_terrain/retroaction_etudiants/Gravel_Stella/courriel_Gravel_Stella.md +2 −2
@@ -1,8 +1,8 @@
1 1 **À :** Stella Gravel
2 2 **Objet :** IMM1033-20 — TP1 corrigé : votre note, la grille de correction et votre classeur annoté
3 3 **Pièces jointes :**
4 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_GRAS76330300_grille_correction.pdf`
5 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_GRAS76330300_corrige_SPB.xlsx`
4 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_GRAS76330300_grille_correction.pdf`
5 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_GRAS76330300_corrige_SPB.xlsx`
6 6
7 7 Bonjour Madame Gravel,
8 8
modified IMM1033-20_Methodes_du_cout/03_Travaux_pratiques/TP1_Evaluation_d_un_terrain/retroaction_etudiants/Jacques_Michele/courriel_Jacques_Michele.md +2 −2
@@ -1,8 +1,8 @@
1 1 **À :** Michèle Jacques
2 2 **Objet :** IMM1033-20 — TP1 corrigé : votre note, la grille de correction et votre classeur annoté
3 3 **Pièces jointes :**
4 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_JACM20518300_grille_correction.pdf`
5 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_JACM20518300_corrige_SPB.xlsx`
4 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_JACM20518300_grille_correction.pdf`
5 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_JACM20518300_corrige_SPB.xlsx`
6 6
7 7 Bonjour Madame Jacques,
8 8
modified IMM1033-20_Methodes_du_cout/03_Travaux_pratiques/TP1_Evaluation_d_un_terrain/retroaction_etudiants/PrudHomme_Erika/courriel_PrudHomme_Erika.md +2 −2
@@ -1,8 +1,8 @@
1 1 **À :** Erika Prud'Homme
2 2 **Objet :** IMM1033-20 — TP1 corrigé : votre note, la grille de correction et votre classeur annoté
3 3 **Pièces jointes :**
4 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_PRUE06519808_grille_correction.pdf`
5 −- `/Users/simon-pierreboucher/Desktop/tp-à-corrigé/correction/TP1_PRUE06519808_corrige_SPB.xlsx`
4 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_PRUE06519808_grille_correction.pdf`
5 +- `/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé/correction/TP1_PRUE06519808_corrige_SPB.xlsx`
6 6
7 7 Bonjour Madame Prud'Homme,
8 8
modified IMM1033-20_Methodes_du_cout/03_Travaux_pratiques/TP1_Evaluation_d_un_terrain/retroaction_etudiants/_outils/make_correction_TP1.py +1 −1
@@ -6,7 +6,7 @@
6 6 """
7 7 import html, math, os, subprocess, csv, sys, shutil
8 8
9 −SRC = "/Users/simon-pierreboucher/Desktop/tp-à-corrigé"
9 +SRC = "/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé"
10 10 OUT = os.path.join(SRC, "correction")
11 11 os.makedirs(OUT, exist_ok=True)
12 12 DATE_CORR = "10 octobre 2026"
modified IMM1033-20_Methodes_du_cout/03_Travaux_pratiques/TP1_Evaluation_d_un_terrain/retroaction_etudiants/_outils/make_correction_TP1_v2.py +1 −1
@@ -10,7 +10,7 @@ import html, math, os, subprocess, csv, sys, importlib
10 10
11 11 HERE = os.path.dirname(os.path.abspath(__file__))
12 12 sys.path.insert(0, HERE)
13 −SRC = os.environ.get("TP_SRC", "/Users/simon-pierreboucher/Desktop/tp-à-corrigé") # TP_SRC/TP_OUT : dossier de travail hors Bureau (Terminal sans accès TCC, 2026-10-27)
13 +SRC = os.environ.get("TP_SRC", "/Users/simon-pierreboucher/Desktop/UQO/Enseignement/corrections/tp-à-corrigé") # TP_SRC/TP_OUT : dossier de travail hors Bureau (Terminal sans accès TCC, 2026-10-27)
14 14 OUT = os.environ.get("TP_OUT", os.path.join(SRC, "correction"))
15 15 os.makedirs(OUT, exist_ok=True); os.makedirs("/tmp/corr", exist_ok=True)
16 16 DATE_CORR = "20 octobre 2026"
modified IMM1033-20_Methodes_du_cout/05_Ressources/scripts_gabarits_excel/make_IMM1033_TP3.py +1 −1
@@ -25,7 +25,7 @@ from uqo_xlsx import (
25 25 table, titre_section, zone_texte,
26 26 )
27 27
28 −OUT = "/Users/simon-pierreboucher/Desktop/UQO/UQO_PREPARATION_COURS/output/IMM1033-20/TP3/IMM1033-20_TP3_gabarit.xlsx"
28 +OUT = "/Users/simon-pierreboucher/Desktop/UQO/Enseignement/UQO_PREPARATION_COURS/output/IMM1033-20/TP3/IMM1033-20_TP3_gabarit.xlsx"
29 29 FMT_D = '#,##0" $"'
30 30 FMT_PSF = '0.00" $/pi²"'
31 31 FMT_P1 = "0.0%"
modified _Suivi_prof/Calendrier_prof_IMM1003_A26.html +1 −1
@@ -6,7 +6,7 @@
6 6 body { font-family: "Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif; color: #111827; font-size: 9pt; margin: 0; }
7 7 .page { page-break-after: always; position: relative; }
8 8 .page:last-child { page-break-after: auto; }
9 −.page::before { content: ""; display: block; height: 12mm; background: url("file:///Users/simon-pierreboucher/Desktop/UQO/UQO_COURS/_Suivi_prof/uqo-logo.png") no-repeat left center; background-size: auto 10.5mm; border-bottom: 2px solid #005f85; margin-bottom: 3.5mm; }
9 +.page::before { content: ""; display: block; height: 12mm; background: url("file:///Users/simon-pierreboucher/Desktop/UQO/Enseignement/UQO_COURS/_Suivi_prof/uqo-logo.png") no-repeat left center; background-size: auto 10.5mm; border-bottom: 2px solid #005f85; margin-bottom: 3.5mm; }
10 10 .page::after { content: "IMM1003 · Automne 2026"; position: absolute; top: 0; right: 0; height: 12mm; line-height: 12mm; font-weight: 600; color: #005f85; font-size: 11pt; letter-spacing: .02em; }
11 11 h1 { font-size: 20pt; font-weight: 700; margin: 0 0 3mm; color: #0f172a; letter-spacing: -.01em; }
12 12 h1 .thin { font-weight: 400; color: #334155; }
modified _Suivi_prof/Calendrier_prof_IMM1033_A26.html +1 −1
@@ -6,7 +6,7 @@
6 6 body { font-family: "Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif; color: #111827; font-size: 9pt; margin: 0; }
7 7 .page { page-break-after: always; position: relative; }
8 8 .page:last-child { page-break-after: auto; }
9 −.page::before { content: ""; display: block; height: 12mm; background: url("file:///Users/simon-pierreboucher/Desktop/UQO/UQO_COURS/_Suivi_prof/uqo-logo.png") no-repeat left center; background-size: auto 10.5mm; border-bottom: 2px solid #005f85; margin-bottom: 3.5mm; }
9 +.page::before { content: ""; display: block; height: 12mm; background: url("file:///Users/simon-pierreboucher/Desktop/UQO/Enseignement/UQO_COURS/_Suivi_prof/uqo-logo.png") no-repeat left center; background-size: auto 10.5mm; border-bottom: 2px solid #005f85; margin-bottom: 3.5mm; }
10 10 .page::after { content: "IMM1033 · Automne 2026"; position: absolute; top: 0; right: 0; height: 12mm; line-height: 12mm; font-weight: 600; color: #005f85; font-size: 11pt; letter-spacing: .02em; }
11 11 h1 { font-size: 20pt; font-weight: 700; margin: 0 0 3mm; color: #0f172a; letter-spacing: -.01em; }
12 12 h1 .thin { font-weight: 400; color: #334155; }
13 13
Menu

Theme