File size: 4,544 Bytes
6f2b94e
37e94dc
6f2b94e
 
37e94dc
 
 
 
 
 
 
99442c4
 
 
 
37e94dc
 
 
 
 
 
 
99442c4
 
 
f3f6557
99442c4
 
 
f3f6557
 
 
 
 
99442c4
 
f3f6557
 
 
 
 
99442c4
 
 
 
37e94dc
99442c4
37e94dc
99442c4
 
 
37e94dc
99442c4
37e94dc
99442c4
 
37e94dc
 
99442c4
37e94dc
99442c4
 
37e94dc
 
99442c4
37e94dc
 
99442c4
 
37e94dc
 
 
 
 
 
 
6f2b94e
37e94dc
 
 
 
87e23e5
 
 
 
 
 
de9b6c1
37e94dc
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import gradio as gr
import ast


def grade(student_code):
    feedback = []
    grade = 10  # Start with full points

    try:
        tree = ast.parse(student_code)

        pin_setup = {"22": False, "15": False}
        button_used = False
        led_toggle_detected = False
        bool_variable_used = False

        for node in ast.walk(tree):
            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):
                            pin_num = str(args[0].value)
                            if pin_num in pin_setup:
                                pin_setup[pin_num] = True
                elif isinstance(node.value, (ast.NameConstant, ast.Constant)) and isinstance(node.targets[0], ast.Name):
                    bool_variable_used = True

            if isinstance(node, ast.If):
                if isinstance(node.test, ast.UnaryOp) and isinstance(node.test.op, ast.Not):
                    if isinstance(node.test.operand, ast.Call) and isinstance(node.test.operand.func, ast.Attribute):
                        if node.test.operand.func.attr == "value":
                            button_used = True
                elif isinstance(node.test, ast.Call) and isinstance(node.test.func, ast.Attribute):
                    if node.test.func.attr == "value":
                        button_used = True
                
                for stmt in node.body:
                    if isinstance(stmt, ast.Assign):
                        if isinstance(stmt.value, ast.UnaryOp) and isinstance(stmt.value.op, ast.Not):
                            led_toggle_detected = True

        if not all(pin_setup.values()):
            feedback.append("⛔️ Pins 22 (LED) and 15 (button) must be correctly set up (-3 pts).")
            grade -= 3
        else:
            feedback.append("✅ Correct pin setup detected (+3 pts).")

        if not button_used:
            feedback.append("⛔️ No button press detection found (-3 pts).")
            grade -= 3
        else:
            feedback.append("✅ Button press detection found (+3 pts).")

        if not led_toggle_detected:
            feedback.append("⛔️ No LED toggle logic detected (-2 pts).")
            grade -= 2
        else:
            feedback.append("✅ LED toggle logic detected (+2 pts).")

        if not bool_variable_used:
            feedback.append("⛔️ No boolean variable found for tracking LED state (-2 pts).")
            grade -= 2
        else:
            feedback.append("✅ Boolean variable found for LED state tracking (+2 pts).")

    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 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)