jan01 commited on
Commit
a47d5fd
Β·
verified Β·
1 Parent(s): e5eed5b

Upload 2 files

Browse files
reports/__pycache__/progress_report.cpython-312.pyc ADDED
Binary file (11.8 kB). View file
 
reports/progress_report.py ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sqlite3
2
+ import pandas as pd
3
+ import matplotlib.pyplot as plt
4
+ import seaborn as sns
5
+ from reportlab.lib.pagesizes import A4
6
+ from reportlab.pdfgen import canvas
7
+ from reportlab.lib.units import inch
8
+ import os
9
+ import tempfile
10
+ import streamlit as st
11
+ import numpy as np
12
+
13
+ def show_progress_report(name):
14
+ st.title("πŸ“ˆ Weekly Progress Report")
15
+
16
+ # Connect to DB and fetch session IDs
17
+ conn = sqlite3.connect("data/mindmentor.db")
18
+ df_sess = pd.read_sql_query("SELECT * FROM user_sessions WHERE name = ?", conn, params=(name,))
19
+ session_ids = tuple(df_sess["id"].tolist())
20
+
21
+ if not session_ids:
22
+ st.warning("No session data found.")
23
+ return
24
+
25
+ def tuple_to_sql(tup):
26
+ return f"({','.join(str(x) for x in tup)})"
27
+
28
+ session_ids_sql = tuple_to_sql(session_ids)
29
+
30
+ # Fetch logs
31
+ df_cog = pd.read_sql_query(f"SELECT * FROM cognitive_logs WHERE session_id IN {session_ids_sql}", conn)
32
+ df_pers = pd.read_sql_query(f"SELECT * FROM personality_logs WHERE session_id IN {session_ids_sql}", conn)
33
+ df_ei = pd.read_sql_query(f"SELECT * FROM ei_logs WHERE session_id IN {session_ids_sql}", conn)
34
+ conn.close()
35
+
36
+ # ---------------- COGNITIVE SUMMARY ----------------
37
+ st.subheader("🧠 Cognitive Task Summary")
38
+ cog_chart_path = None
39
+ if not df_cog.empty:
40
+ # Exclude unwanted tasks
41
+ df_cog = df_cog[~df_cog["task_name"].isin(["stroop_test", "symbol_match"])]
42
+ if not df_cog.empty:
43
+ cog_summary = df_cog.groupby("task_name").agg({
44
+ "score": "mean",
45
+ "reaction_time": "mean"
46
+ }).round(2)
47
+ st.dataframe(cog_summary)
48
+
49
+ fig1, ax1 = plt.subplots()
50
+ cog_summary["score"].plot(kind="bar", ax=ax1, color="lightblue")
51
+ ax1.set_title("Cognitive Task Scores")
52
+ ax1.set_ylabel("Score")
53
+ plt.tight_layout()
54
+ cog_chart_path = os.path.join(tempfile.gettempdir(), "cog_chart.png")
55
+ plt.savefig(cog_chart_path)
56
+ st.image(cog_chart_path)
57
+ else:
58
+ cog_summary = pd.DataFrame()
59
+ st.info("No valid cognitive task data (after filtering).")
60
+ else:
61
+ cog_summary = pd.DataFrame()
62
+ st.info("No cognitive data found.")
63
+
64
+ # ---------------- PERSONALITY RADAR ----------------
65
+ st.subheader("🧬 Personality Trait Summary")
66
+ radar_path = None
67
+ if not df_pers.empty:
68
+ pers_summary = df_pers.groupby("trait").agg({"score": "mean"}).round(2)
69
+ st.dataframe(pers_summary)
70
+
71
+ fig2 = plt.figure(figsize=(5, 5))
72
+ categories = list(pers_summary.index)
73
+ values = pers_summary["score"].tolist()
74
+ values += values[:1]
75
+ angles = [n / float(len(categories)) * 2 * np.pi for n in range(len(categories))]
76
+ angles += angles[:1]
77
+ ax2 = plt.subplot(111, polar=True)
78
+ ax2.plot(angles, values, linewidth=2, linestyle='solid')
79
+ ax2.fill(angles, values, 'skyblue', alpha=0.4)
80
+ ax2.set_xticks(angles[:-1])
81
+ ax2.set_xticklabels(categories)
82
+ ax2.set_title("Big Five Personality Traits")
83
+ radar_path = os.path.join(tempfile.gettempdir(), "radar_chart.png")
84
+ plt.tight_layout()
85
+ plt.savefig(radar_path)
86
+ st.image(radar_path)
87
+ else:
88
+ pers_summary = pd.DataFrame()
89
+ st.info("No personality data found.")
90
+
91
+ # ---------------- EI DRILL HEATMAP ----------------
92
+ st.subheader("πŸ’– EI Drill Activity")
93
+ heatmap_path = None
94
+ if not df_ei.empty:
95
+ ei_counts = df_ei.groupby("drill_type").size().reset_index(name="Count")
96
+ heatmap_data = ei_counts.pivot_table(index="drill_type", values="Count")
97
+
98
+ fig3, ax3 = plt.subplots(figsize=(4, 3))
99
+ sns.heatmap(heatmap_data, annot=True, cmap="YlGnBu", ax=ax3)
100
+ ax3.set_title("EI Drill Frequency")
101
+ heatmap_path = os.path.join(tempfile.gettempdir(), "ei_heatmap.png")
102
+ plt.tight_layout()
103
+ plt.savefig(heatmap_path)
104
+ st.image(heatmap_path)
105
+ else:
106
+ ei_counts = pd.DataFrame()
107
+ st.info("No EI drill data found.")
108
+
109
+ # ---------------- RECOMMENDATIONS ----------------
110
+ st.subheader("🎯 Personalized Recommendations")
111
+ reco_lines = []
112
+
113
+ # Low personality traits
114
+ if not pers_summary.empty:
115
+ low_traits = pers_summary[pers_summary['score'] < 3.0]
116
+ if not low_traits.empty:
117
+ reco_lines.append("Based on your Big Five traits, you may consider the following:")
118
+ for trait in low_traits.index:
119
+ reco_lines.append(f"β€’ Improve {trait} through daily habits and journaling.")
120
+
121
+ # Low EI drills
122
+ if not df_ei.empty:
123
+ drill_freq = df_ei['drill_type'].value_counts()
124
+ if drill_freq.min() < 3:
125
+ reco_lines.append("You're missing out on some EI drills. Try doing more of:")
126
+ underdone = drill_freq[drill_freq < 3].index.tolist()
127
+ reco_lines.extend([f"β€’ {d}" for d in underdone])
128
+
129
+ if reco_lines:
130
+ for line in reco_lines:
131
+ st.markdown(line)
132
+ else:
133
+ st.info("You're doing great! No specific recommendations this week.")
134
+
135
+ # ---------------- PDF EXPORT ----------------
136
+ if st.button("πŸ“„ Download Weekly Report (PDF)"):
137
+ pdf_path = os.path.join(tempfile.gettempdir(), "weekly_report.pdf")
138
+ c = canvas.Canvas(pdf_path, pagesize=A4)
139
+ width, height = A4
140
+ margin = 50
141
+ y = height - margin
142
+
143
+ def draw_text_block(title, lines, c, y):
144
+ c.setFont("Helvetica-Bold", 14)
145
+ c.drawString(margin, y, title)
146
+ y -= 20
147
+ c.setFont("Helvetica", 12)
148
+ for line in lines:
149
+ if y < 100:
150
+ c.showPage()
151
+ y = height - margin
152
+ c.setFont("Helvetica", 12)
153
+ c.drawString(margin + 10, y, line)
154
+ y -= 15
155
+ return y - 20
156
+
157
+ def draw_image_fullpage(path, title):
158
+ if path and os.path.exists(path):
159
+ c.showPage()
160
+ c.setFont("Helvetica-Bold", 14)
161
+ c.drawString(margin, height - margin - 20, title)
162
+ c.drawImage(path, margin, height / 2 - 200, width=5.5 * inch, preserveAspectRatio=True)
163
+
164
+ # PAGE 1: Text Summary
165
+ c.setFont("Helvetica-Bold", 16)
166
+ c.drawString(margin, y, f"MindMentor Report for {name}")
167
+ y -= 30
168
+
169
+ cog_lines = [f"{task}: Score={row['score']} | RT={row['reaction_time']}s"
170
+ for task, row in cog_summary.iterrows()] if not cog_summary.empty else ["No cognitive data available."]
171
+ pers_lines = [f"{trait}: {row['score']}" for trait, row in pers_summary.iterrows()] if not pers_summary.empty else ["No personality data available."]
172
+ ei_lines = [f"{row['drill_type']}: {row['Count']} times" for _, row in ei_counts.iterrows()] if not ei_counts.empty else ["No EI drill data available."]
173
+
174
+ y = draw_text_block("🧠 Cognitive Task Summary:", cog_lines, c, y)
175
+ y = draw_text_block("🧬 Personality Trait Summary:", pers_lines, c, y)
176
+ y = draw_text_block("πŸ’– EI Drill Activity:", ei_lines, c, y)
177
+
178
+ # PAGE 2-4: Charts
179
+ draw_image_fullpage(cog_chart_path, "πŸ“Š Cognitive Task Chart")
180
+ draw_image_fullpage(radar_path, "🧠 Personality Radar Chart")
181
+ draw_image_fullpage(heatmap_path, "πŸ’– EI Drill Heatmap")
182
+
183
+ c.save()
184
+ with open(pdf_path, "rb") as f:
185
+ st.download_button("πŸ“₯ Download PDF", f, file_name="MindMentor_Report.pdf")