Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from openai import OpenAI | |
| import os | |
| from linear_equilibrium_calculations import extract_numbers, calculate_linear_equilibrium | |
| from plot_functions import plot_equilibrium | |
| from PIL import Image | |
| import json | |
| from openai import OpenAI | |
| # β Load API Key from secrets.json | |
| with open("secrets.json", "r") as f: | |
| secrets = json.load(f) | |
| client = OpenAI(api_key=secrets["OPENAI_API_KEY"]) | |
| # β API Budget Tracking | |
| total_tokens_used = 0 | |
| budget_limit = 10_000_000 # ~10M tokens (~$20 cap) | |
| # β Store equation values & student responses | |
| stored_equations = {} | |
| student_responses = {} | |
| question_index = 0 | |
| current_mode = None # Track user mode | |
| # β Essay Questions | |
| essay_questions = [ | |
| "What do you think is the biggest challenge in balancing farming and environmental protection?", | |
| "Should farmers bear the full cost of pollution control, or should society share the responsibility? Why?", | |
| "Would taxing pollution from farms be Pareto optimal? Why or why not?", | |
| "Should farmers act based on Kantian ethics (duty) or utilitarianism (maximizing benefits)?", | |
| "If pollution reduction benefits cities more than it costs farmers, should the policy be adopted?", | |
| "What would you propose as a fair and effective policy to manage farm runoff?" | |
| ] | |
| # β AI-Enhanced Response Generator (Critique + Improvement) | |
| def generate_improved_response(user_input): | |
| """Uses GPT-3.5 to critique and improve student responses.""" | |
| global total_tokens_used | |
| prompt = f""" | |
| The following is a student's response to an essay question. Your job is to critique it constructively, refine it for clarity, and enhance it while keeping the student's original intent. | |
| - **Critique the response constructively.** | |
| - **Improve clarity, structure, and argumentation.** | |
| - **Preserve the studentβs original ideas.** | |
| - **DO NOT replace the response with an unrelated definition.** | |
| **Student Response:** "{user_input}" | |
| **Critique & AI-Enhanced Version:** | |
| """ | |
| try: | |
| response = client.chat.completions.create( | |
| model="gpt-3.5-turbo", | |
| messages=[{"role": "system", "content": "You are a writing assistant that critiques and refines student responses while keeping their original intent intact."}, | |
| {"role": "user", "content": prompt}], | |
| max_tokens=200 | |
| ) | |
| total_tokens_used += response.usage.total_tokens | |
| if total_tokens_used > budget_limit: | |
| return "β Budget limit reached. AI responses disabled." | |
| ai_response = response.choices[0].message.content.strip() | |
| if not ai_response: | |
| return "β οΈ AI failed to generate an improved response. Please try again." | |
| return ai_response | |
| except Exception as e: | |
| return f"β οΈ Error: Unable to process AI request. {str(e)}" | |
| # β AI-Enhanced Essay Outline Generator | |
| def generate_essay_outline(responses): | |
| """Creates an AI-enhanced essay outline while keeping student responses.""" | |
| enhanced_responses = [ | |
| f"**Student Response:** {responses[i]}\n\n**AI Feedback & Refinement:** {generate_improved_response(responses[i])}" | |
| for i in range(len(responses)) | |
| ] | |
| outline = f"""**Title:** Addressing Agricultural Runoff: A Balanced Approach | |
| **Introduction:** | |
| - Discuss the importance of agriculture and its environmental trade-offs. | |
| - {enhanced_responses[0]} | |
| **Body Paragraphs:** | |
| 1. **Equity in Pollution Control:** | |
| - {enhanced_responses[1]} | |
| 2. **Economic Efficiency & Policy:** | |
| - {enhanced_responses[2]} | |
| 3. **Ethical Perspectives in Farming:** | |
| - {enhanced_responses[3]} | |
| 4. **Policy Recommendations & Feasibility:** | |
| - {enhanced_responses[4]} | |
| **Conclusion:** | |
| - {enhanced_responses[5]} | |
| - Implementing practical solutions to ensure sustainability in agriculture. | |
| """ | |
| return outline | |
| # β Chatbot Logic (Includes Both Essay & Equilibrium Features) | |
| def chatbot(user_input): | |
| global stored_equations, student_responses, question_index, current_mode | |
| user_input = user_input.strip() | |
| # β Ensure correct mode selection | |
| if user_input.lower() == "start": | |
| return "Do you want to solve an **equilibrium problem** or work on an **essay**? Type 'equilibrium' or 'essay'.", None | |
| if user_input.lower() == "equilibrium": | |
| current_mode = "equilibrium" | |
| return ("You've selected **Competitive Equilibrium**. Enter demand and supply equations in this format:\n\n" | |
| "Demand: P = 100 - 2Q\n" | |
| "Supply: P = 20 + 3Q\n\n" | |
| "Then type 'solve' to compute equilibrium."), None | |
| if user_input.lower() == "essay": | |
| current_mode = "essay" | |
| student_responses.clear() | |
| question_index = 0 | |
| return f"Let's build your essay! First question:\n\n{essay_questions[question_index]}", None | |
| # β Handle Essay Mode Responses (Now Includes Critique) | |
| if current_mode == "essay": | |
| if question_index < len(essay_questions): | |
| improved_answer = generate_improved_response(user_input) | |
| student_responses[question_index] = user_input | |
| question_index += 1 | |
| if question_index < len(essay_questions): | |
| return f"Next question:\n\n{essay_questions[question_index]}", None | |
| else: | |
| outline = generate_essay_outline(student_responses) | |
| return f"β Your AI-enhanced essay outline is ready:\n\n{outline}", None | |
| # β Handle Competitive Equilibrium Inputs | |
| if current_mode == "equilibrium": | |
| if "p =" in user_input: | |
| numbers = extract_numbers(user_input) | |
| if len(numbers) != 4 or any(n is None for n in numbers): | |
| return "Invalid equation format. Please enter it as: Demand: P = a - bQ, Supply: P = c + dQ.", None | |
| stored_equations = { | |
| "demand_intercept": numbers[0], | |
| "demand_slope": -abs(numbers[1]), | |
| "supply_intercept": numbers[2], | |
| "supply_slope": abs(numbers[3]) | |
| } | |
| return (f"Stored equations:\n" | |
| f" Demand: P = {stored_equations['demand_intercept']} - {abs(stored_equations['demand_slope'])}Q\n" | |
| f" Supply: P = {stored_equations['supply_intercept']} + {stored_equations['supply_slope']}Q\n\n" | |
| f"Type 'solve' to calculate equilibrium."), None | |
| if user_input.lower() == "solve": | |
| if not stored_equations: | |
| return "Error: Missing equations. Please enter them first.", None | |
| Q_eq, P_eq = calculate_linear_equilibrium(**stored_equations) | |
| plot_path, CS, PS = plot_equilibrium(**stored_equations) | |
| return (f"β Equilibrium Found:\n" | |
| f" Quantity: {Q_eq}\n" | |
| f" Price: {P_eq}\n" | |
| f" Consumer Surplus: {CS}\n" | |
| f" Producer Surplus: {PS}"), plot_path | |
| return "Type 'start' to begin an equilibrium problem or an essay.", None | |
| # β Launch Gradio (Essay + Equilibrium Fully Integrated) | |
| interface = gr.Interface( | |
| fn=chatbot, | |
| inputs="text", | |
| outputs=["text", "image"], | |
| title="AGEC 3503 HW Bot", | |
| description="Type 'start' for equilibrium problems or 'essay' for an AI-enhanced essay outline." | |
| ) | |
| interface.launch(share=True) | |