push-button / app.py
bgaultier's picture
Update app.py
f3f6557 verified
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)