SNT

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

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>