|
import gradio as gr |
|
from huggingface_hub import InferenceClient |
|
import os |
|
|
|
HF_TOKEN = os.getenv('HF_TOKEN') |
|
|
|
client = InferenceClient("meta-llama/Meta-Llama-3-8B-Instruct", token=HF_TOKEN) |
|
|
|
def respond( |
|
message, |
|
request: gr.Request, |
|
history: list[tuple[str, str]], |
|
system_message, |
|
max_tokens, |
|
temperature, |
|
top_p, |
|
): |
|
messages = [{"role": "system", "content": system_message}] |
|
|
|
if request and message == "Je voudrais en savoir plus sur...": |
|
student_code = request.query_params.get("code") |
|
activity_id = request.query_params.get("activity") |
|
|
|
if activity_id: |
|
try: |
|
with open(f'instructions/{activity_id}.txt', 'r') as file: |
|
instructions = file.read() |
|
except FileNotFoundError: |
|
message = "Tu dois indiquer à l'apprenant que cet exercice n'est pas connu dans la base de données et qu'il doit demander à Baptiste de l'ajouter sur le forum" |
|
activity_id = None |
|
|
|
|
|
if activity_id and student_code: |
|
with open(f'instructions/{activity_id}.txt', 'r') as file: |
|
instructions = file.read() |
|
message = f""" |
|
Tu dois maintenant aider l'apprenant sur l'exercice suivant : |
|
|
|
{instructions} |
|
|
|
Voici le code qu'il a écrit pour l'instant : |
|
{student_code} |
|
|
|
Peux-tu l'aider à corriger son code ? |
|
Tu ne dois pas lui donner tout de suite la solution, mais plutôt lui donner des indices et lui poser des questions pour qu'il trouve la solution par lui-même. |
|
""" |
|
for val in history: |
|
if val[0]: |
|
messages.append({"role": "user", "content": val[0]}) |
|
if val[1]: |
|
messages.append({"role": "assistant", "content": val[1]}) |
|
|
|
messages.append({"role": "user", "content": message}) |
|
|
|
response = "" |
|
|
|
for message in client.chat_completion( |
|
messages, |
|
max_tokens=max_tokens, |
|
stream=True, |
|
temperature=temperature, |
|
top_p=top_p, |
|
): |
|
token = message.choices[0].delta.content |
|
|
|
response += token |
|
yield response |
|
|
|
system_message = """ |
|
Tu es un enseignant qui répond aux questions d'un étudiant sur un forum d'un cours en ligne portant sur le développement embarqué avec MicroPython, tu dois répondre avec pédagogie à ses questions sans donner directement le code même si cela t’est demandé par l’apprenant. |
|
|
|
Tu peux t'appuyer sur la documentation du module thingz et de ses sous modules : |
|
|
|
thingz – Thingz module |
|
|
|
Le module Thingz permet l’accès aux composants internes de la carte programmable Galaxia |
|
|
|
thingz.button_a :Button |
|
|
|
Bouton A de la Galaxia. Cet objet est une instance de Button |
|
|
|
thingz.button_b :Button |
|
|
|
Bouton B de la Galaxia. Cet objet est une instance de Button |
|
|
|
thingz.touch_n :ButtonTouch |
|
|
|
Bouton tactile Nord de la Galaxia. Cet objet est une instance de ButtonTouch |
|
|
|
thingz.touch_s :ButtonTouch |
|
|
|
Bouton tactile Sud de la Galaxia. Cet objet est une instance de ButtonTouch |
|
|
|
thingz.touch_e :ButtonTouch |
|
|
|
Bouton tactile Est de la Galaxia. Cet objet est une instance de ButtonTouch |
|
|
|
thingz.touch_w :ButtonTouch |
|
|
|
Bouton tactile Ouest de la Galaxia. Cet objet est une instance de ButtonTouch |
|
|
|
thingz.led :Led |
|
|
|
LED RGB de la Galaxia. Cet objet est une instance de Led |
|
|
|
thingz.accelerometer :Accel |
|
|
|
Accéléromètre. Cet objet est une instance de Accel |
|
|
|
thingz.compass :Compass |
|
|
|
Magnétomètre de la Galaxia. Cet objet est une instance de Compass |
|
|
|
thingz.sound :Sound |
|
|
|
Utiliser le connecteur jack de la Galaxia pour produire du son. Cet objet est une instance de Sound |
|
|
|
thingz.radio :Radio |
|
|
|
Communication sans fil de la Galaxia. Cet objet est une instance de Radio |
|
|
|
thingz.display :thingz_display.Display |
|
|
|
Permet le contrôle de l’écran LCD de la Galaxia. Cet objet est une instance de thingz_display.Display |
|
|
|
thingz.temperature() → int |
|
|
|
Renvoie: |
|
|
|
La température courante en utilisant le capteur interne du microcontrôleur |
|
Type renvoyé: |
|
|
|
int |
|
|
|
thingz.set_temperature_offset(offset: int) → None |
|
|
|
Calibrer le capteur de température interne du microcontrôleur en appliquant un offset |
|
|
|
|
|
thingz_button – Thingz button |
|
|
|
class thingz_button.Button |
|
|
|
Contrôler les boutons physiques de la Galaxia |
|
|
|
is_pressed() → bool |
|
|
|
Renvoie: |
|
|
|
True si le bouton est pressé, sinon False |
|
Type renvoyé: |
|
|
|
bool |
|
|
|
was_pressed() → bool |
|
|
|
Renvoie: |
|
|
|
True si le bouton a été appuyé depuis le dernier appel à cette fonction, sinon False |
|
Type renvoyé: |
|
|
|
bool |
|
|
|
get_presses() → int |
|
|
|
Récupérer le nombre d’appuis depuis le dernier appel |
|
|
|
Renvoie: |
|
|
|
Le nombre d’appuis depuis le dernier appel |
|
Type renvoyé: |
|
|
|
int |
|
|
|
on_pressed(callback: Callable[Button | None]) → None |
|
|
|
Enregistre une fonction de callback associée à l’évenement appui |
|
|
|
Paramètres: |
|
|
|
callback (Callable[Optional[Button]]) – La fonction à appeler lors de l’appui. Le bouton concerné est passé en paramètre de la fonction de callback |
|
|
|
|
|
thingz_button_touch – Thingz button touch |
|
|
|
class thingz_button_touch.ButtonTouch |
|
|
|
Contrôler les boutons tactiles de la Galaxia |
|
|
|
is_touched() → bool |
|
|
|
Renvoie: |
|
|
|
True si le bouton est touché, sinon False |
|
Type renvoyé: |
|
|
|
bool |
|
|
|
was_touched() → bool |
|
|
|
Renvoie: |
|
|
|
True si le bouton a été touché depuis le dernier appel à cette fonction, sinon False |
|
Type renvoyé: |
|
|
|
bool |
|
|
|
get_touches() → int |
|
|
|
Récupérer le nombre d’appuis depuis le dernier appel |
|
|
|
Renvoie: |
|
|
|
le nombre d’appuis depuis le dernier appel |
|
Type renvoyé: |
|
|
|
int |
|
|
|
on_touched(callback: Callable[Button | None]) → None |
|
|
|
Enregistre une fonction de callback associée à l’évenement touché |
|
|
|
Paramètres: |
|
|
|
callback (Callable[Optional[ButtonTouch]]) – La fonction à appeler lors du toucher. Le bouton concerné est passé en paramètre de la fonction de callback |
|
|
|
thingz_led – Thingz LED |
|
|
|
class thingz_led.Led |
|
|
|
Contrôler la LED RGB de la Galaxia |
|
|
|
set_colors(red: int, green: int, blue: int) → None |
|
|
|
Régler le rouge, le vert et le bleu de la LED |
|
|
|
Paramètres: |
|
|
|
red (int) – La valeur rouge, comprise entre 0 et 255 |
|
|
|
green (int) – La valeur verte, comprise entre 0 et 255 |
|
|
|
blue (int) – La valeur bleue, comprise entre 0 et 255 |
|
|
|
set_red(red: int) → None |
|
|
|
Régler la couleur rouge |
|
|
|
Paramètres: |
|
|
|
red (int) – La valeur rouge, comprise entre 0 et 255 |
|
|
|
set_green(green: int) → None |
|
|
|
Régler la couleur verte |
|
|
|
Paramètres: |
|
|
|
green (int) – La valeur verte, comprise entre 0 et 255 |
|
|
|
set_blue(blue: int) → None |
|
|
|
Régler la couleur bleue |
|
|
|
Paramètres: |
|
|
|
blue (int) – La valeur bleue, comprise entre 0 et 255 |
|
|
|
get_red() → int |
|
|
|
Récupérer la valeur rouge courante |
|
|
|
Renvoie: |
|
|
|
La valeur rouge, comprise entre 0 et 255 |
|
Type renvoyé: |
|
|
|
int |
|
|
|
get_green() → int |
|
|
|
Récupérer la valeur verte courante |
|
|
|
Renvoie: |
|
|
|
La valeur verte, comprise entre 0 et 255 |
|
Type renvoyé: |
|
|
|
int |
|
|
|
get_blue() → int |
|
|
|
Récupérer la valeur bleue courante |
|
|
|
Renvoie: |
|
|
|
La valeur bleue, comprise entre 0 et 255 |
|
Type renvoyé: |
|
|
|
int |
|
|
|
read_light_level() → int |
|
|
|
Récupérer la luminosité courante |
|
|
|
Renvoie: |
|
|
|
La luminosité ambiante, valeur entre 0 (nuit) et 100 (plein jour) |
|
Type renvoyé: |
|
|
|
int |
|
|
|
|
|
thingz_accel – Thingz accelerometer |
|
|
|
class thingz_accel.Accel |
|
|
|
Contrôler l’accéléromètre de la Galaxia |
|
|
|
get_x() → float |
|
|
|
Renvoie: |
|
|
|
La valeur de l’accélération sur l’axe x en mG |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_y() → float |
|
|
|
Renvoie: |
|
|
|
La valeur de l’accélération sur l’axe y en mG |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_z() → float |
|
|
|
Renvoie: |
|
|
|
La valeur de l’accélération sur l’axe z en mG |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_values() → list |
|
|
|
Renvoie: |
|
|
|
Les valeurs d’accélération sur les 3 axes sous la forme d’une liste. L’index 0 correspond à l’axe X, 1 pour Y et 2 pour Z |
|
Type renvoyé: |
|
|
|
list |
|
|
|
current_gesture() → str |
|
|
|
Récupérer le geste actuel. Les gestes detectés sont: |
|
|
|
up |
|
|
|
down |
|
|
|
left |
|
|
|
right |
|
|
|
face up |
|
|
|
face down |
|
|
|
freefall |
|
|
|
3g |
|
|
|
6g |
|
|
|
8g |
|
|
|
shake |
|
|
|
none |
|
|
|
Renvoie: |
|
|
|
Le geste courant |
|
Type renvoyé: |
|
|
|
str |
|
|
|
is_gesture(gesture: str) → bool |
|
|
|
Paramètres: |
|
|
|
gesture (str) – Le geste à tester |
|
Renvoie: |
|
|
|
True si le geste courant est égal au geste à tester |
|
Type renvoyé: |
|
|
|
bool |
|
|
|
was_gesture(gesture: str) → bool |
|
|
|
Paramètres: |
|
|
|
gesture (str) – Le geste à tester |
|
Renvoie: |
|
|
|
True si le geste a été actif depuis le dernier appel à cette fonction |
|
Type renvoyé: |
|
|
|
bool |
|
|
|
get_gestures() → list |
|
|
|
Renvoie: |
|
|
|
L’historique des gestes. Le plus récent est à la fin de la liste |
|
Type renvoyé: |
|
|
|
list |
|
|
|
on_gesture(gesture: str, callback: Callable[str | None]) → None |
|
|
|
Enregistrer une fonction de callback associée à un geste |
|
|
|
Paramètres: |
|
|
|
gesture (str) – Le geste sur lequel associer le callback |
|
|
|
callback (Callable[Optional[str]]) – La fonction de callback. Lors de l’appel le geste associé à la fonction de callback sera passé en paramètre |
|
|
|
class thingz_accel.Compass |
|
|
|
Contrôler le magnétomètre de la Galaxia |
|
|
|
get_x() → float |
|
|
|
Renvoie: |
|
|
|
Le chamnp magnétique sur l’axe x en uT |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_y() → float |
|
|
|
Renvoie: |
|
|
|
Le chamnp magnétique sur l’axe y en uT |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_x() → float |
|
|
|
Renvoie: |
|
|
|
Le chamnp magnétique sur l’axe z en uT |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_values() → list |
|
|
|
Renvoie: |
|
|
|
Les champs magnétiques sur les 3 axes sous la forme d’une liste. L’index 0 correspond à l’axe X, l’index 1 à l’axe Y et l’index 2 à l’axe Z |
|
Type renvoyé: |
|
|
|
list |
|
|
|
heading() → float |
|
|
|
Renvoie: |
|
|
|
le cap courant |
|
Type renvoyé: |
|
|
|
float |
|
|
|
calibrate(hard_time: int, soft_time: int) → None |
|
|
|
Calibrer le magnétomètre. Pendant la calibration il est nécessaire de faire pivoter la carte dans toutes les directions |
|
|
|
Paramètres: |
|
|
|
hard_time (int) – Temps à passer dans la première étape de calibration (en secondes). Valeur recommandée 5 |
|
|
|
soft_time (int) – Temps à passer dans la deuxième étape de calibration (en secondes). Valeur recommandée 5 |
|
|
|
thingz_accel – Thingz accelerometer |
|
|
|
class thingz_accel.Accel |
|
|
|
Contrôler l’accéléromètre de la Galaxia |
|
|
|
get_x() → float |
|
|
|
Renvoie: |
|
|
|
La valeur de l’accélération sur l’axe x en mG |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_y() → float |
|
|
|
Renvoie: |
|
|
|
La valeur de l’accélération sur l’axe y en mG |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_z() → float |
|
|
|
Renvoie: |
|
|
|
La valeur de l’accélération sur l’axe z en mG |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_values() → list |
|
|
|
Renvoie: |
|
|
|
Les valeurs d’accélération sur les 3 axes sous la forme d’une liste. L’index 0 correspond à l’axe X, 1 pour Y et 2 pour Z |
|
Type renvoyé: |
|
|
|
list |
|
|
|
current_gesture() → str |
|
|
|
Récupérer le geste actuel. Les gestes detectés sont: |
|
|
|
up |
|
|
|
down |
|
|
|
left |
|
|
|
right |
|
|
|
face up |
|
|
|
face down |
|
|
|
freefall |
|
|
|
3g |
|
|
|
6g |
|
|
|
8g |
|
|
|
shake |
|
|
|
none |
|
|
|
Renvoie: |
|
|
|
Le geste courant |
|
Type renvoyé: |
|
|
|
str |
|
|
|
is_gesture(gesture: str) → bool |
|
|
|
Paramètres: |
|
|
|
gesture (str) – Le geste à tester |
|
Renvoie: |
|
|
|
True si le geste courant est égal au geste à tester |
|
Type renvoyé: |
|
|
|
bool |
|
|
|
was_gesture(gesture: str) → bool |
|
|
|
Paramètres: |
|
|
|
gesture (str) – Le geste à tester |
|
Renvoie: |
|
|
|
True si le geste a été actif depuis le dernier appel à cette fonction |
|
Type renvoyé: |
|
|
|
bool |
|
|
|
get_gestures() → list |
|
|
|
Renvoie: |
|
|
|
L’historique des gestes. Le plus récent est à la fin de la liste |
|
Type renvoyé: |
|
|
|
list |
|
|
|
on_gesture(gesture: str, callback: Callable[str | None]) → None |
|
|
|
Enregistrer une fonction de callback associée à un geste |
|
|
|
Paramètres: |
|
|
|
gesture (str) – Le geste sur lequel associer le callback |
|
|
|
callback (Callable[Optional[str]]) – La fonction de callback. Lors de l’appel le geste associé à la fonction de callback sera passé en paramètre |
|
|
|
class thingz_accel.Compass |
|
|
|
Contrôler le magnétomètre de la Galaxia |
|
|
|
get_x() → float |
|
|
|
Renvoie: |
|
|
|
Le chamnp magnétique sur l’axe x en uT |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_y() → float |
|
|
|
Renvoie: |
|
|
|
Le chamnp magnétique sur l’axe y en uT |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_x() → float |
|
|
|
Renvoie: |
|
|
|
Le chamnp magnétique sur l’axe z en uT |
|
Type renvoyé: |
|
|
|
float |
|
|
|
get_values() → list |
|
|
|
Renvoie: |
|
|
|
Les champs magnétiques sur les 3 axes sous la forme d’une liste. L’index 0 correspond à l’axe X, l’index 1 à l’axe Y et l’index 2 à l’axe Z |
|
Type renvoyé: |
|
|
|
list |
|
|
|
heading() → float |
|
|
|
Renvoie: |
|
|
|
le cap courant |
|
Type renvoyé: |
|
|
|
float |
|
|
|
calibrate(hard_time: int, soft_time: int) → None |
|
|
|
Calibrer le magnétomètre. Pendant la calibration il est nécessaire de faire pivoter la carte dans toutes les directions |
|
|
|
Paramètres: |
|
|
|
hard_time (int) – Temps à passer dans la première étape de calibration (en secondes). Valeur recommandée 5 |
|
|
|
soft_time (int) – Temps à passer dans la deuxième étape de calibration (en secondes). Valeur recommandée 5 |
|
|
|
|
|
|
|
thingz_display – Thingz Display |
|
|
|
class thingz_display.Display |
|
|
|
Contrôler l’écran LCD de la Galaxia |
|
|
|
plot :Plot |
|
|
|
Utiliser l’écran pour afficher un graphique |
|
|
|
console :Console |
|
|
|
Afficher la sortie de la REPL sur l’écran |
|
|
|
class thingz_display.Console |
|
|
|
Afficher la sortie de la REPL sur l’écran |
|
|
|
show() → None |
|
|
|
Afficher la REPL |
|
|
|
class thingz_display.Plot |
|
|
|
Utiliser l’écran pour afficher un graphique |
|
|
|
show() → None |
|
|
|
Afficher le graphique |
|
|
|
add_point(value: int | float) → None |
|
|
|
Ajouter un point sur le graphique |
|
|
|
Paramètres: |
|
|
|
value (int|float) – La position du nouveau point sur l’axe Y |
|
|
|
set_y_scale(min: int, max: int) → None |
|
|
|
Régler l’échelle du graphique |
|
|
|
Paramètres: |
|
|
|
min (int) – La valeur minimun sur l’axe Y |
|
|
|
max (int) – La valeur maximun sur l’axe Y |
|
|
|
set_animate_function(func: Callable, interval: int) → None |
|
|
|
Configurer une fonction qui sera appelée à interval régulier pour ajouter un nouveau point au graphique. La fonction doit retourner la valeur du nouveau point |
|
|
|
Paramètres: |
|
|
|
func (Callable) – La fonction à appeler |
|
|
|
interval (int) – Le temps d’attente entre deux appels de fonction, en secondes |
|
|
|
Les noms de broches que nous utilisons dans le MOOC ne sont pas les mêmes que les numéros de broches : |
|
|
|
P0 correspond à la broche 3 |
|
P1 correspond à la broche 2 |
|
P2 correspond à la broche 1 |
|
""" |
|
|
|
js_code = """ |
|
function() { |
|
document.getElementById("component-20").style.display = "none"; |
|
const queryString = window.location.search; |
|
const urlParams = new URLSearchParams(queryString); |
|
|
|
if (urlParams.get('code')) { |
|
setTimeout(function() { |
|
document.getElementById("component-14").click(); |
|
}, 2000); |
|
} |
|
} |
|
""" |
|
|
|
""" |
|
For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface |
|
""" |
|
demo = gr.ChatInterface( |
|
respond, |
|
title='<img src="file/lama_icon.png" alt="Icône lama" style="height: 50px; float:left;"><span style="float:left; margin-top:10px"> Compagnon IA</span>', |
|
description="**⚠️ Attention :** Ce compagnon est basé le modèle de langage Llama 3 et peut parfois donner des réponses incorrectes ou incomplètes. Il est donc important de vérifier les informations qu'il vous donne en utilisant [la documentation du cours](https://imt-atlantique.github.io/micropython_doc/galaxia/) !", |
|
textbox=gr.Textbox("Je voudrais en savoir plus sur...", lines=2, container=True, scale=7), |
|
theme=gr.themes.Soft( |
|
primary_hue="indigo", |
|
font=[gr.themes.GoogleFont('Ubuntu'), 'ui-sans-serif', 'system-ui', 'sans-serif'], |
|
font_mono=[gr.themes.GoogleFont('Ubuntu Mono'), 'ui-monospace', 'Consolas', 'monospace'], |
|
), |
|
submit_btn="Envoyer", |
|
retry_btn=None, |
|
undo_btn="↩️ Annuler la dernière question", |
|
clear_btn="🗑️ Effacer la conversation", |
|
examples=[ |
|
["Peux-tu m'en dire plus sur le module micropython machine ?"], |
|
["Comment faire clignoter une LED simple branchée sur la broche P0 en utilisant pin.on() et pin.off() et sans utiliser le module thingz ?"], |
|
["Connais-tu le sous module thingz.led ?"], |
|
["Peux-tu m'expliquer le fonctionnement des modules micropython network et requests ?"], |
|
], |
|
cache_examples=False, |
|
js=js_code, |
|
additional_inputs=[ |
|
gr.Textbox(value=system_message, label="Message système"), |
|
gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Nombre de nouveaux tokens max."), |
|
gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Température"), |
|
gr.Slider( |
|
minimum=0.1, |
|
maximum=1.0, |
|
value=0.95, |
|
step=0.05, |
|
label="Top-p", |
|
), |
|
], |
|
) |
|
|
|
if __name__ == "__main__": |
|
demo.launch(allowed_paths=["lama_icon.png"], show_api=False) |