suivi.html (7347B)
1 <head> 2 3 <meta charset="utf-8"/> 4 5 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"/> 6 7 <style> 8 h1,h2 { 9 font-family: Sans; 10 } 11 12 .stderr { 13 background-color: #fee; 14 color: #900; 15 } 16 17 .stderr, .stdout { 18 /* display: contents; */ /* uncomment to make print( end='') work */ 19 margin: 0px; 20 padding: 0px 0.3em; 21 } 22 23 .console { 24 max-height: 20em; 25 overflow: auto; 26 border: medium solid black; 27 } 28 29 .console:empty { 30 display: none; 31 } 32 33 #feedback { 34 border: solid #aaa; 35 background-color: #eee; 36 } 37 38 #feedback:empty { 39 display: none; 40 } 41 42 </style> 43 44 <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script> 45 <script src="https://unpkg.com/brython@3.9.3/brython.js"></script> 46 <script src="https://unpkg.com/brython@3.9.3/brython_stdlib.js"></script> 47 <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.min.js"></script> 48 <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/mode-python.min.js"></script> 49 50 <script type="text/javascript"> 51 52 code = "# Écrivez votre code python ici :\nprint(\"Bonjour !\")"; 53 54 score = 0; 55 56 API = window.API || window.parent.API; 57 58 function loadSCO() { 59 if (API) { 60 API.LMSInitialize(""); 61 62 suspend_data = API.LMSGetValue("cmi.suspend_data"); 63 64 if (suspend_data) { 65 code = suspend_data; 66 } 67 } 68 } 69 70 function sendSCO() { 71 if (API) { 72 API.LMSSetValue("cmi.core.score.raw", score); 73 API.LMSSetValue("cmi.suspend_data", code); 74 API.LMSSetValue("cmi.core.score.lesson_status", "completed"); 75 76 API.LMSCommit(""); 77 } 78 } 79 80 function nextSCO() { 81 if (API) { 82 API.LMSSetValue("nav.event","continue"); // Probably Moodle specific 83 API.LMSFinish(""); 84 } 85 } 86 87 // Leaflet stuff 88 89 cognac = [45.69, -0.32]; 90 91 markers = []; 92 click_latlng = {"lat":45.69, "lng":-0.32}; 93 click_func = function() {}; 94 95 function clear_map() { 96 while (markers.length > 0) { 97 markers.pop().remove(); 98 } 99 } 100 101 function on_map_click(e) { 102 //document.getElementById("lastclick").innerHTML = e.latlng.lat+", "+e.latlng.lng; 103 click_latlng = e.latlng; 104 click_func(); 105 check(); 106 } 107 108 window.onload = function() { 109 loadSCO(); 110 document.getElementById("code").textContent = code; 111 112 map = L.map('map').setView(cognac, 11); 113 L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map); 114 map.on("click", on_map_click); 115 116 brython(); 117 } 118 </script> 119 120 <script type="text/python"> 121 # Requires Brython and Ace editor 122 123 from browser import document, window, html 124 from sys import stderr, stdout, settrace 125 from traceback import print_exc, extract_stack, extract_tb 126 127 def make_max_line_tracer(maxlines): 128 lines = 0 129 def tracer(frame, event, arg): 130 nonlocal lines 131 if event == 'line': 132 lines += 1 133 if lines >= maxlines: 134 raise TimeoutError 135 return tracer 136 return tracer 137 138 def exec_code(editor, id): 139 effacer() 140 141 console = document[id + "_console"] 142 console.clear() 143 stderr.write = lambda data : console_target(data, console, True) 144 stdout.write = lambda data : console_target(data, console) 145 146 code = editor.getValue() 147 try: 148 compiled = compile(code, "<" + id + ">", "exec") 149 except SyntaxError: 150 print_exc(limit=0) 151 return 152 153 settrace(make_max_line_tracer(10000)) # increase to allow longer execution 154 try: 155 exec(code) 156 except TimeoutError: 157 settrace(None) 158 print("L'exécution prend trop de temps, abandon.", file=stderr) 159 except Exception as e: 160 settrace(None) 161 tb_len = len(extract_tb(e.__traceback__)) - len(extract_stack()) 162 print_exc(limit=-tb_len) 163 finally: 164 settrace(None) 165 166 window.code = code 167 window.score = score 168 window.sendSCO() 169 170 def console_target(data, elt, err=False): 171 elt <= html.PRE(data, Class="stderr" if err else "stdout") 172 elt.scrollTop = elt.scrollHeight 173 174 breditors = document.select(".breditor") 175 176 for ed_elt in breditors: 177 editor = window.ace.edit(ed_elt.id) 178 editor.session.setMode("ace/mode/python") 179 #editor.setOption('fontSize', '14px') 180 editor.setOption('maxLines', 15) 181 182 console = html.DIV(Class="console", id=ed_elt.id + "_console") 183 184 ed_elt.insertAdjacentElement('afterend', console) 185 186 exec_button = html.BUTTON("Exécuter →") 187 exec_button.bind("click", lambda ev : exec_code(editor, ed_elt.id)) 188 ed_elt.insertAdjacentElement('afterend', exec_button) 189 190 def feedback(msg): 191 document["feedback"].clear() 192 document["feedback"] <= msg 193 194 markers = window.markers 195 L = window.L 196 map = window.map 197 198 def marqueur(lat, lon, message=None): 199 mark=L.marker((lat, lon)).addTo(map) 200 markers.append(mark) 201 202 if message: 203 mark.bindPopup(message) 204 205 def cercle(lat, lon, rad, col='red', message=None): 206 mark=L.circle((lat, lon), 207 {"color": col, 208 "fillColor": col, 209 "fillOpacity": 0.5, 210 "radius": rad} 211 ).addTo(map) 212 markers.append(mark) 213 214 if message: 215 mark.bindPopup(message) 216 217 218 def dernier_clic(): 219 return window.click_latlng["lat"], window.click_latlng["lng"] 220 221 def au_clic(func): 222 window.click_func = func 223 224 def effacer(): 225 window.clear_map() 226 227 score = 0 228 229 def check(): 230 global score 231 score = 0 232 233 if len(markers) == 0: 234 feedback("Aucun marqueur placé") 235 elif len(markers) >1: 236 score = 10 237 feedback("trop de marqueurs") 238 239 else: 240 clatlng = window.click_latlng 241 latlng = markers[0].getLatLng() 242 if latlng["lat"] != clatlng["lat"]: 243 score = 30 244 feedback("Les coordonnées du marqueur ne sont pas les bonnes") 245 else: 246 score = 100 247 feedback("Le marqueur est bien placé, bravo ! ") 248 document["feedback"] <= html.BUTTON("Passer à la suite", onclick="nextSCO();") 249 250 return score 251 252 window.check = check 253 254 </script> 255 256 </head> 257 258 <body> 259 260 <h1>Suivi de la souris</h1> 261 262 <div> 263 On veut maintenant que le code permette de réagir et de déplacer un marqueur 264 dès qu'on clique quelque part avec la souris.<br/> 265 Pour ça il faudra : 266 <ol> 267 <li>Créer une fonction qui contient le code pour afficher un marqueur 268 à la position du dernier clic. On crée une fonction de la manière 269 suivante : 270 <pre><code>def nom_de_fontion(): 271 # contenu de la fonction : 272 truc() 273 machin() 274 </code></pre> 275 </li> 276 <li>Demander à ce que la fonction soit appelée à chaque fois qu'on en utilisant 277 <code>au_clic(nom_de_fonction)</code> 278 </li> 279 <li>Ne pas oublier d'effacer le marqueur précédent au bon moment en 280 utilisant la fonction <code>effacer()</code> 281 (qui efface tous les éléments de la carte) 282 </li> 283 </ol> 284 <div> 285 <b> 286 Écrivez le code python qui fait qu'un marqueur se déplace au clic de la souris. 287 </b> 288 </div> 289 <div> 290 <i>Rappel : <code>marqueur(latitude, longitude)</code> 291 </i> 292 </div> 293 <div> 294 <i>Rappel : <code>lat, lon = dernier_clic()</code> 295 </i> 296 </div> 297 298 <h2>Carte OpenStreetMap</h2> 299 300 <div id = "map" style = "width: 900px; height: 580px"></div> 301 302 <button onclick="clear_map();">Tout effacer sur la carte</button> 303 <span id="lastclick"></span> 304 305 <h2>Code Python</h2> 306 307 <pre id="code" class="breditor"></pre> 308 <div id="feedback"></div> 309 310 </body> 311 </html>