EssayHW2 / app.py
jeffrey1963's picture
Upload 2 files
eb862bc verified
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)