Spaces:
Sleeping
Sleeping
| 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() |