import gradio as gr import ast def grade(student_code): feedback = [] grade = 10 # Start with full score try: tree = ast.parse(student_code) has_i2s_import = False has_json_import = False has_network_connect = False has_http_post = False has_rms_calc = False has_dB_conversion = False has_send_loop = False for node in ast.walk(tree): # Check for import statements if isinstance(node, ast.ImportFrom): if node.module == "machine": for alias in node.names: if alias.name == "I2S": has_i2s_import = True if isinstance(node, ast.Import): for alias in node.names: if alias.name == "json": has_json_import = True if alias.name == "network": has_network_connect = True # Look for RMS calculation if isinstance(node, ast.FunctionDef): if "rms" in node.name.lower(): has_rms_calc = True if "db" in node.name.lower(): has_dB_conversion = True # Look for HTTP POST request if isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute): if node.func.attr.lower() == "post": has_http_post = True # Look for loop to continuously send data if isinstance(node, ast.While): has_send_loop = True if not has_i2s_import: feedback.append("⛔️ Missing import of I2S from machine (-2 pts).") grade -= 2 else: feedback.append("✅ I2S import detected (+1 pt).") if not has_network_connect: feedback.append("⛔️ No WiFi network connection found (-2 pts).") grade -= 2 else: feedback.append("✅ WiFi connection setup found (+1 pt).") if not has_rms_calc: feedback.append("⛔️ No RMS calculation function found (-2 pts).") grade -= 2 else: feedback.append("✅ RMS calculation function detected (+1 pt).") if not has_dB_conversion: feedback.append("⛔️ No conversion to decibels found (-1 pt).") grade -= 1 else: feedback.append("✅ Decibel conversion function found (+1 pt).") if not has_http_post: feedback.append("⛔️ No HTTP POST request found (-2 pts).") grade -= 2 else: feedback.append("✅ HTTP POST request detected (+1 pt).") if not has_send_loop: feedback.append("⚠️ No loop to continuously send data (not penalized).") else: feedback.append("✅ Loop to send data detected.") except Exception as e: feedback = [f"⛔️ Error parsing code: {e}"] grade = 0 grade = max(0, grade) grade = f"{grade}/10" feedback = "\n".join(feedback) return grade, feedback # Interface Gradio seulement si le script est exécuté directement if __name__ == "__main__": with gr.Blocks(gr.themes.Default(primary_hue="cyan")) as demo: with gr.Row(): instructions = gr.Markdown(""" ## Instructions 1. Based on the examples you've seen so far, write a MicroPython code that follows the instructions above. 2. You can use the [Vittascience simulator](https://fr.vittascience.com/esp32/?mode=code&console=bottom&toolbox=scratch&simu=1&board=basic-esp32) to test your code. 2. Click the "Grade" button to get a grade and feedback. 3. Make sure your code is well-structured and efficient. 4. When you're happy with your code, please upload your solution below to get graded. 6. Good luck! """, container=False) code = gr.Code(label="MicroPython code", language="python", value='import time\nimport network\nimport requests\n# Your code here', lines=24) with gr.Row(): feedback_output = gr.Textbox(label="Feedback", value="Click on the 'Grade' button to get feedback", interactive=False, scale=4) grade_output = gr.Textbox(label="Grade", interactive=False, value="0/10", scale=1) grade_btn = gr.Button("Grade", variant="primary") grade_btn.click(fn=grade, inputs=code, outputs=[grade_output, feedback_output], api_name="grade") demo.launch(show_error=False, allowed_paths=["/assets", "assets"], show_api=False)