Spaces:
Runtime error
Runtime error
import gradio as gr | |
import openai | |
import os | |
# Fetch the API key from Gradio secrets | |
api_key = os.getenv("OPENAI_API_KEY") | |
if api_key is None: | |
raise ValueError("API key not found. Please set the OPENAI_API_KEY secret.") | |
openai.api_key = api_key | |
def generate_exercise_question(topic): | |
try: | |
messages = [{"role": "system", "content": "You are an AI tutor specialized in teaching Python programming. Your task is to create exercise questions based on the given topic. Provide clear, concise, and informative exercises. Include a specific task for the user to implement, along with example input and expected output."}] | |
messages.append({"role": "user", "content": f"Create an exercise question on {topic} with a specific task, example input, and expected output."}) | |
response = openai.ChatCompletion.create( | |
model="gpt-3.5-turbo", | |
messages=messages, | |
max_tokens=250, | |
n=1, | |
stop=None, | |
temperature=0.7, | |
) | |
question = response.choices[0].message['content'].strip() | |
return question | |
except Exception as e: | |
return f"Error: {str(e)}" | |
def check_answer(topic, exercise, user_code): | |
try: | |
messages = [{"role": "system", "content": "You are an AI tutor specialized in teaching Python programming. Your task is to evaluate the user's code for the given exercise. Provide feedback on correctness and suggest improvements if needed."}] | |
messages.append({"role": "user", "content": f"Evaluate this answer for the exercise on {topic}: \nExercise: {exercise}\nUser's code: {user_code}"}) | |
response = openai.ChatCompletion.create( | |
model="gpt-3.5-turbo", | |
messages=messages, | |
max_tokens=250, | |
n=1, | |
stop=None, | |
temperature=0.7, | |
) | |
feedback = response.choices[0].message['content'].strip() | |
return feedback | |
except Exception as e: | |
return f"Error: {str(e)}" | |
def get_solution(topic, exercise): | |
try: | |
messages = [{"role": "system", "content": "You are an AI tutor specialized in teaching Python programming. Your task is to provide a correct solution for the given exercise."}] | |
messages.append({"role": "user", "content": f"Provide the correct solution code for this exercise on {topic}: {exercise}"}) | |
response = openai.ChatCompletion.create( | |
model="gpt-3.5-turbo", | |
messages=messages, | |
max_tokens=250, | |
n=1, | |
stop=None, | |
temperature=0.7, | |
) | |
solution = response.choices[0].message['content'].strip() | |
return solution | |
except Exception as e: | |
return f"Error: {str(e)}" | |
def is_python_topic(topic): | |
try: | |
messages = [{"role": "system", "content": "You are an AI assistant that determines if a given topic is related to Python programming. Respond with only 'Yes' or 'No'."}] | |
messages.append({"role": "user", "content": f"Is '{topic}' a topic related to Python programming?"}) | |
response = openai.ChatCompletion.create( | |
model="gpt-3.5-turbo", | |
messages=messages, | |
max_tokens=10, | |
n=1, | |
stop=None, | |
temperature=0.3, | |
) | |
answer = response.choices[0].message['content'].strip().lower() | |
return answer == "yes" | |
except Exception as e: | |
return False | |
def process_input(user_input, code_input, chat_history, current_topic): | |
if not chat_history: | |
# First interaction: set topic and generate question | |
current_topic = user_input | |
question = generate_exercise_question(current_topic) | |
chat_history.append((user_input, question)) | |
return "", chat_history, current_topic, gr.update(visible=True, value="") | |
elif code_input.strip(): | |
# User submitted code | |
exercise = chat_history[-1][1] # Get the last exercise question | |
feedback = check_answer(current_topic, exercise, code_input) | |
if "correct" in feedback.lower(): | |
response = f"{feedback}\n\nGreat job! Type 'next' for a new question on {current_topic}, or enter a new Python topic to switch subjects." | |
else: | |
solution = get_solution(current_topic, exercise) | |
response = f"{feedback}\n\nHere's the correct solution:\n\n{solution}\n\nType 'next' for a new question on {current_topic}, or enter a new Python topic to switch subjects." | |
chat_history.append((code_input, response)) | |
return "", chat_history, current_topic, gr.update(visible=True, value="") | |
else: | |
# Check if user wants next question or new topic | |
if user_input.lower() == "next": | |
question = generate_exercise_question(current_topic) | |
chat_history.append((user_input, question)) | |
elif is_python_topic(user_input): | |
current_topic = user_input | |
question = generate_exercise_question(current_topic) | |
chat_history.append((user_input, f"Switching to new topic: {current_topic}\n\n{question}")) | |
else: | |
chat_history.append((user_input, f"'{user_input}' doesn't seem to be a Python topic. Please enter a valid Python topic or 'next' for a new question on {current_topic}.")) | |
return "", chat_history, current_topic, gr.update(visible=True, value="") | |
def undo(chat_history, current_topic): | |
if chat_history: | |
chat_history.pop() | |
return chat_history, current_topic, gr.update(visible=bool(chat_history)) | |
def clear(): | |
return [], "", gr.update(visible=False, value="") | |
with gr.Blocks() as demo: | |
gr.Markdown("# Python Practice Bot") | |
gr.Markdown("Learn Python through exercises. Start by entering a topic you want to practice.") | |
chatbot = gr.Chatbot(label="Python Tutor") | |
current_topic = gr.State("") | |
with gr.Row(): | |
with gr.Column(scale=3): | |
user_input = gr.Textbox( | |
show_label=False, | |
placeholder="Enter a Python topic, type 'next' for a new question, or submit your code...", | |
lines=1 | |
) | |
code_input = gr.Code(language="python", label="Your Solution", visible=False) | |
with gr.Column(scale=1): | |
submit_button = gr.Button("Submit") | |
undo_button = gr.Button("Undo") | |
clear_button = gr.Button("Clear") | |
submit_button.click( | |
process_input, | |
[user_input, code_input, chatbot, current_topic], | |
[user_input, chatbot, current_topic, code_input] | |
) | |
undo_button.click(undo, [chatbot, current_topic], [chatbot, current_topic, code_input]) | |
clear_button.click(clear, None, [chatbot, current_topic, code_input]) | |
gr.Examples( | |
examples=[["lists"], ["decorators"], ["dictionaries"], ["file handling"], ["classes and objects"]], | |
inputs=[user_input] | |
) | |
demo.launch() | |