StudyPlanner / app.py
syuanteng315's picture
Update app.py
d86c288 verified
import gradio as gr
import pandas as pd
from fpdf import FPDF
import sib_api_v3_sdk
import base64
import json
import os
class AdaptiveAI:
def __init__(self, subjects, scores_list):
self.df = pd.DataFrame({
"Subject": subjects,
"Score": [int(s) for s in scores_list]
})
self.days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
def generate_plan(self, feedback_data=None):
def get_base_settings(score):
if score < 40: return 150, "Focus on fundamental concepts."
if score < 65: return 120, "Practice more topical questions."
if score < 80: return 90, "Review mistakes & past year papers."
return 60, "Quick revision & advance topics."
self.df['Time_Mins'], self.df['Advice'] = zip(*self.df['Score'].apply(get_base_settings))
self.df = self.df.sort_values(by='Score').reset_index(drop=True)
self.df['Day'] = self.days[:len(self.df)]
if feedback_data:
for fb in feedback_data:
sub = fb['Subject']
idx = self.df[self.df['Subject'] == sub].index
if not idx.empty:
current_t = self.df.loc[idx, 'Time_Mins'].values[0]
if fb['Status'] == 'stuck' or fb['Level'] <= 2:
self.df.loc[idx, 'Time_Mins'] = current_t + 30
elif fb['Status'] == 'finished' and fb['Level'] >= 4:
self.df.loc[idx, 'Time_Mins'] = max(45, current_t - 20)
return self.df
def create_pdf(df):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", 'B', 16)
pdf.cell(0, 15, "AI ADAPTIVE STUDY PLAN", ln=True, align='C')
pdf.set_font("Arial", size=10)
for _, row in df.iterrows():
line = f"{row['Day']} | {row['Subject']} | {row['Time_Mins']} mins | {row['Advice']}"
pdf.cell(0, 10, line, ln=True, border=1)
pdf_path = "study_plan.pdf"
pdf.output(pdf_path)
return pdf_path
def send_email(email_to, pdf_path):
api_key = "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"
configuration = sib_api_v3_sdk.Configuration()
configuration.api_key['api-key'] = api_key
api_instance = sib_api_v3_sdk.TransactionalEmailsApi(sib_api_v3_sdk.ApiClient(configuration))
with open(pdf_path, "rb") as f:
pdf_b64 = base64.b64encode(f.read()).decode('utf-8')
smtp_email = sib_api_v3_sdk.SendSmtpEmail(
to=[{"email": email_to}],
sender={"name": "AI Tutor", "email": "syuantengzhiya@gmail.com"},
subject="Your New Study Plan",
html_content="<p>Attached is your personalized plan.</p>",
attachment=[{"content": pdf_b64, "name": "Plan.pdf"}]
)
api_instance.send_transac_email(smtp_email)
def api_interface(student_email, subjects_json, scores_json, feedback_json=None):
try:
subjects = json.loads(subjects_json) # ["Math", "Science", ...]
scores = json.loads(scores_json) # [75, 60, ...]
feedback = json.loads(feedback_json) if feedback_json and feedback_json.strip() else None
engine = AdaptiveAI(subjects, scores)
plan_df = engine.generate_plan(feedback)
pdf_file = create_pdf(plan_df)
send_email(student_email, pdf_file)
result = plan_df[['Day','Subject','Time_Mins','Advice']].to_dict('records')
return json.dumps(result)
except Exception as e:
return f"Error: {str(e)}"
demo = gr.Interface(
fn=api_interface,
inputs=[
gr.Textbox(label="Email"),
gr.Textbox(label="Subjects JSON"), # ["Math","Science",...]
gr.Textbox(label="Scores JSON"), # [75, 60, ...]
gr.Textbox(label="Feedback JSON")
],
outputs="text"
)
demo.launch()