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="
Attached is your personalized plan.
", 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()