Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import ast | |
| def grade(student_code): | |
| feedback = [] | |
| grade = 10 # Start with full points | |
| try: | |
| # Parse the student's code into an AST (Abstract Syntax Tree) | |
| tree = ast.parse(student_code) | |
| # Variables to track correctness | |
| pin_setup = False | |
| initial_delay = False | |
| loop_found = False | |
| blink_pattern = False | |
| sleep_times = [] | |
| # Analyze the AST | |
| for node in ast.walk(tree): | |
| # Check pin setup | |
| if isinstance(node, ast.Assign): | |
| if isinstance(node.value, ast.Call) and isinstance(node.value.func, ast.Attribute): | |
| if node.value.func.attr == "Pin": | |
| args = node.value.args | |
| if len(args) >= 2 and isinstance(args[0], ast.Constant): | |
| if str(args[0].value) == "21": | |
| pin_setup = True | |
| # Check for time.sleep() calls | |
| if isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute): | |
| if node.func.attr == "sleep" and isinstance(node.args[0], ast.Constant): | |
| sleep_times.append(node.args[0].value) | |
| # Check for while loop | |
| if isinstance(node, ast.While): | |
| loop_found = True | |
| # Check LED alternation | |
| if isinstance(node, ast.Expr) and isinstance(node.value, ast.Call): | |
| if isinstance(node.value.func, ast.Attribute): | |
| if node.value.func.attr == "value" or node.value.func.attr == "on" or node.value.func.attr == "off": | |
| blink_pattern = True | |
| # Validate pin setup | |
| if not pin_setup: | |
| feedback.append("⛔️ Pin 21 must be correctly set as an output (-2 pts).") | |
| grade -= 2 | |
| else: | |
| feedback.append("✅ Correct pin setup detected (+2 pts).") | |
| # Validate initial delay | |
| if 3 in sleep_times: | |
| initial_delay = True | |
| feedback.append("✅ Initial delay of 3 seconds detected (+2 pts).") | |
| else: | |
| feedback.append("⛔️ The LED must stay ON for 3 seconds initially (-2 pts).") | |
| grade -= 2 | |
| # Validate while loop | |
| if not loop_found: | |
| feedback.append("⛔️ No `while True:` loop found! The LED must blink continuously (-2 pts).") | |
| grade -= 2 | |
| else: | |
| feedback.append("✅ Infinite loop detected (+2 pts).") | |
| # Validate blinking pattern | |
| if 1 in sleep_times: | |
| feedback.append("✅ Blinking delay of 1 second detected (+2 pts).") | |
| else: | |
| feedback.append("⛔️ The LED must blink every second after the initial delay (-2 pts).") | |
| grade -= 2 | |
| # Validate LED alternation | |
| if not blink_pattern: | |
| feedback.append("⛔️ The LED should alternate states in the loop (-2 pts).") | |
| grade -= 2 | |
| else: | |
| feedback.append("✅ LED alternation detected (+2 pts).") | |
| except Exception as e: | |
| feedback = f"Error parsing code: {e}" | |
| # Ensure the grade is not negative | |
| grade = max(0, grade) | |
| grade = f"{grade}/10" | |
| feedback = "\n".join(feedback) | |
| # Return 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 machine\n\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) |