SNT

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

cercle.html (6975B)


      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 ou cercle placé")
    231     else:
    232         exists = False
    233         radius = 0
    234         for m in markers:
    235             if "_radius" in m:
    236                 radius = m.getRadius()
    237                 exists = True
    238         if not exists:
    239             score = 30
    240             feedback("Il y a des marqueurs, mais pas de cercle")
    241         elif radius != 10000:
    242             score = 60
    243             feedback("Le rayon ne fait pas 10km")
    244         else:
    245             score = 100
    246             feedback("Le cercle semble correct, bravo ! ")
    247             document["feedback"] <= html.BUTTON("Passer à la suite", onclick="nextSCO();")
    248 
    249     return score
    250 
    251 </script>
    252 
    253 </head>
    254 
    255 <body>
    256 
    257 <h1>Un cercle</h1>
    258 
    259 <div>
    260 On peut aussi afficher des cercles : on utilise
    261 la fonction <code>cercle(latitude, longitude, rayon)</code>
    262 (le rayon est donné en mètres).
    263 Ou alors la variante
    264 <code>cercle(latitude, longitude, rayon, couleur)</code>
    265 où couleur une du texte (en anglais), exemple :
    266 </div>
    267 <pre><code>cercle(45.69, -0.32, 2000, 'blue')
    268 </code></pre>
    269 <div>
    270 <b>
    271 Écrivez le code python qui dessine un cercle de 10km autour de chez vous.
    272 </b>
    273 (même si les mesures sanitaires n'imposent plus d'y rester ...)
    274 </div>
    275 <div>
    276 <i>On pourra encore se servir du fait que les coordonnées du clic sont
    277 affichées sous la carte.
    278 </i>
    279 </div>
    280 
    281 <h2>Carte OpenStreetMap</h2>
    282 
    283 <div id = "map" style = "width: 900px; height: 580px"></div>
    284 
    285 <button onclick="clear_map();">Tout effacer sur la carte</button>
    286 Coordonnées du dernier clic :
    287 <span id="lastclick"></span>
    288 
    289 <h2>Code Python</h2>
    290 
    291 <pre id="code" class="breditor"></pre>
    292 <div id="feedback"></div>
    293 
    294 </body>
    295 </html>