souris.html (7082B)
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 } 106 107 window.onload = function() { 108 loadSCO(); 109 document.getElementById("code").textContent = code; 110 111 map = L.map('map').setView(cognac, 11); 112 L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map); 113 map.on("click", on_map_click); 114 115 brython(); 116 } 117 </script> 118 119 <script type="text/python"> 120 # Requires Brython and Ace editor 121 122 from browser import document, window, html 123 from sys import stderr, stdout, settrace 124 from traceback import print_exc, extract_stack, extract_tb 125 126 def make_max_line_tracer(maxlines): 127 lines = 0 128 def tracer(frame, event, arg): 129 nonlocal lines 130 if event == 'line': 131 lines += 1 132 if lines >= maxlines: 133 raise TimeoutError 134 return tracer 135 return tracer 136 137 def exec_code(editor, id): 138 effacer() 139 140 console = document[id + "_console"] 141 console.clear() 142 stderr.write = lambda data : console_target(data, console, True) 143 stdout.write = lambda data : console_target(data, console) 144 145 code = editor.getValue() 146 try: 147 compiled = compile(code, "<" + id + ">", "exec") 148 except SyntaxError: 149 print_exc(limit=0) 150 return 151 152 settrace(make_max_line_tracer(10000)) # increase to allow longer execution 153 try: 154 exec(code) 155 except TimeoutError: 156 settrace(None) 157 print("L'exécution prend trop de temps, abandon.", file=stderr) 158 except Exception as e: 159 settrace(None) 160 tb_len = len(extract_tb(e.__traceback__)) - len(extract_stack()) 161 print_exc(limit=-tb_len) 162 finally: 163 settrace(None) 164 165 window.code = code 166 window.score = check() 167 window.sendSCO() 168 169 def console_target(data, elt, err=False): 170 elt <= html.PRE(data, Class="stderr" if err else "stdout") 171 elt.scrollTop = elt.scrollHeight 172 173 breditors = document.select(".breditor") 174 175 for ed_elt in breditors: 176 editor = window.ace.edit(ed_elt.id) 177 editor.session.setMode("ace/mode/python") 178 #editor.setOption('fontSize', '14px') 179 editor.setOption('maxLines', 15) 180 181 console = html.DIV(Class="console", id=ed_elt.id + "_console") 182 183 ed_elt.insertAdjacentElement('afterend', console) 184 185 exec_button = html.BUTTON("Exécuter →") 186 exec_button.bind("click", lambda ev : exec_code(editor, ed_elt.id)) 187 ed_elt.insertAdjacentElement('afterend', exec_button) 188 189 def feedback(msg): 190 document["feedback"].clear() 191 document["feedback"] <= msg 192 193 markers = window.markers 194 L = window.L 195 map = window.map 196 197 def marqueur(lat, lon, message=None): 198 mark=L.marker((lat, lon)).addTo(map) 199 markers.append(mark) 200 201 if message: 202 mark.bindPopup(message) 203 204 def cercle(lat, lon, rad, col='red', message=None): 205 mark=L.circle((lat, lon), 206 {"color": col, 207 "fillColor": col, 208 "fillOpacity": 0.5, 209 "radius": rad} 210 ).addTo(map) 211 markers.append(mark) 212 213 if message: 214 mark.bindPopup(message) 215 216 217 def dernier_clic(): 218 return window.click_latlng["lat"], window.click_latlng["lng"] 219 220 def au_clic(func): 221 window.click_func = func 222 223 def effacer(): 224 window.clear_map() 225 226 def check(): 227 score = 0 228 229 if len(markers) == 0: 230 feedback("Aucun marqueur placé") 231 else: 232 clatlng = window.click_latlng 233 latlng = markers[0].getLatLng() 234 if latlng["lat"] != clatlng["lat"]: 235 score = 30 236 feedback("Les coordonnées du marqueur ne sont pas les bonnes") 237 else: 238 score = 100 239 feedback("Le marqueur est bien placé, bravo ! ") 240 document["feedback"] <= html.BUTTON("Passer à la suite", onclick="nextSCO();") 241 242 return score 243 244 </script> 245 246 </head> 247 248 <body> 249 250 <h1>Les coordonnées du clic</h1> 251 252 <div> 253 L'affichage des coordonnées du clic précédent est maintenant désactivé, 254 mais j'ai laissé une fonction pour retrouver les coordonnées. 255 C'est la fonction <code>dernier_clic()</code>, qui ne prend pas de 256 paramètre, mais renvoie 2 valeurs : la latitude et la longitude du 257 dernier clic fait sur la carte. 258 <br/> 259 On peut donc récupérer ces coordonées en créant 2 variables qu'on pourra 260 réutiliser plus tard : 261 </div> 262 <pre><code>lat, lon = dernier_clic() 263 print(lat) 264 print(lon) 265 </code></pre> 266 <div> 267 <b> 268 Écrivez le code python qui place un marqueur à la position du dernier clic. 269 </b> 270 </div> 271 <div> 272 <i>Rappel : <code>marqueur(latitude, longitude)</code> 273 </i> 274 </div> 275 <div> 276 <i>Optionnel : utilisez la forme 277 <code>marqueur(latitude, longitude, message)</code> 278 pour mettre les coordonnées du clic dans le message du marqueur. 279 (<code>str()</code> permet de transformer quelque chose en texte) 280 </i> 281 </div> 282 283 <h2>Carte OpenStreetMap</h2> 284 285 <div id = "map" style = "width: 900px; height: 580px"></div> 286 287 <button onclick="clear_map();">Tout effacer sur la carte</button> 288 <span id="lastclick"></span> 289 290 <h2>Code Python</h2> 291 292 <pre id="code" class="breditor"></pre> 293 <div id="feedback"></div> 294 295 </body> 296 </html>