SNT

Cours de SNT
git clone git://git.vgx.fr/SNT
Log | Files | Refs

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>