anly656 commited on
Commit
e2d76f8
·
verified ·
1 Parent(s): 46309d7

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -60
app.py CHANGED
@@ -85,7 +85,21 @@ def scan_slides(client, image_paths):
85
  temperature=0.1
86
  )
87
  )
88
- inventory.append(json.loads(response.text))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  except Exception as e:
90
  print(f"Error scanning slide {slide_num}: {e}")
91
 
@@ -95,79 +109,97 @@ def scan_slides(client, image_paths):
95
  # LOGIC: PASS 2 (COACH CRITIQUE)
96
  # -----------------------------------------------------------------------------
97
  def generate_critique(client, inventory):
98
- # Filter Appendix
99
- def get_title(slide):
100
- t = slide.get("title")
101
- return t if t else ""
 
 
 
 
 
102
 
103
- active = [s for s in inventory if "appendix" not in get_title(s).lower()]
104
-
105
- # Script
106
- script = []
107
- for s in active:
108
- visuals = s.get("visual_elements", {})
109
- busy = "BUSY" if visuals.get("is_busy") else "OK"
110
- entry = f"Slide {s['slide_number']}: {s.get('title')}\n- Content: {s.get('key_takeaway')}\n- Visuals: {busy}"
111
- script.append(entry)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
- full_text = "\n".join(script)
114
-
115
- # THE MENTOR PROMPT (Synced with run_pass_2_gemini.py)
116
- prompt = f"""
117
- You are Dr. Jones, an expert Data Science Mentor.
118
- Your goal is to guide a student to professional excellence.
119
-
120
- SLIDE INVENTORY:
121
- {full_text}
122
-
123
- TASK:
124
- Coach this student based on the 8-Step Story Arc.
125
-
126
- REQUIRED STORY ARC:
127
- 1. Executive Summary
128
- 2. Data Description
129
- 3. Targets & Metrics
130
- 4. Model Candidates
131
- 5. HPO Strategy
132
- 6. Best Model Selection
133
- 7. Validation
134
- 8. Business Impact
135
-
136
- INSTRUCTIONS:
137
- 1. **Fill the Roadmap**: For each of the 8 steps above, determine status (✅, ⚠️, ❓, ⭕).
138
- 2. **Slide Refs**: Cite specific slide numbers in the notes.
139
- 3. **Tone**: Encouraging.
140
- 4. **Summary**: Write a robust 2-paragraph summary (approx 150 words) explaining the overall impression and main areas for improvement.
141
-
142
- OUTPUT JSON SCHEMA:
143
- {{
144
- "overall_summary": "Encouraging feedback (2 paragraphs).",
145
- "structure_roadmap": [
146
- {{
147
- "step_name": "String (e.g. '1. Exec Summary')",
148
- "status_icon": "String (✅, ⚠️, ❓, ⭕)",
149
- "coach_notes": "String"
150
- }}
151
- ]
152
- }}
153
- """
154
-
155
- try:
156
  response = client.models.generate_content(
157
  model=MODEL_NAME,
158
  contents=prompt,
159
  config=types.GenerateContentConfig(response_mime_type="application/json")
160
  )
161
  print("DEBUG: Received Pass 2 Response from Gemini.")
162
- # print(response.text) # Uncomment to see raw JSON if needed
163
- return json.loads(response.text)
 
 
 
 
 
 
 
 
 
 
164
 
165
  except Exception as e:
166
  print(f"CRITICAL ERROR in Pass 2: {e}")
167
  # Return a fallback critique so the UI doesn't hang
168
  return {
169
  "overall_summary": f"Error generating critique: {e}",
170
- "roadmap": [],
171
  "slide_tips": []
172
  }
173
 
 
85
  temperature=0.1
86
  )
87
  )
88
+ data = json.loads(response.text)
89
+
90
+ # Robustness: Handle case where model returns a list [ { ... } ] instead of { ... }
91
+ if isinstance(data, list):
92
+ if len(data) > 0 and isinstance(data[0], dict):
93
+ data = data[0]
94
+ else:
95
+ print(f"Warning: Slide {slide_num} returned a list without a dict. Skipping.")
96
+ data = None
97
+
98
+ if isinstance(data, dict):
99
+ inventory.append(data)
100
+ else:
101
+ print(f"Warning: Slide {slide_num} did not return a valid JSON dictionary. Data: {data}")
102
+
103
  except Exception as e:
104
  print(f"Error scanning slide {slide_num}: {e}")
105
 
 
109
  # LOGIC: PASS 2 (COACH CRITIQUE)
110
  # -----------------------------------------------------------------------------
111
  def generate_critique(client, inventory):
112
+ try:
113
+ # Filter Appendix (Robustly)
114
+ def get_title(slide):
115
+ if not isinstance(slide, dict): return ""
116
+ t = slide.get("title")
117
+ return t if t else ""
118
+
119
+ # Ensure 's' is a dict before accessing
120
+ active = [s for s in inventory if isinstance(s, dict) and "appendix" not in get_title(s).lower()]
121
 
122
+ # Script
123
+ script = []
124
+ for s in active:
125
+ visuals = s.get("visual_elements", {})
126
+ if not isinstance(visuals, dict): visuals = {} # Safety
127
+
128
+ busy = "BUSY" if visuals.get("is_busy") else "OK"
129
+ title = s.get('title', 'No Title')
130
+ num = s.get('slide_number', '?')
131
+ takeaway = s.get('key_takeaway', '')
132
+
133
+ entry = f"Slide {num}: {title}\n- Content: {takeaway}\n- Visuals: {busy}"
134
+ script.append(entry)
135
+
136
+ full_text = "\n".join(script)
137
+
138
+ # THE MENTOR PROMPT (Synced with run_pass_2_gemini.py)
139
+ prompt = f"""
140
+ You are Dr. Jones, an expert Data Science Mentor.
141
+ Your goal is to guide a student to professional excellence.
142
+
143
+ SLIDE INVENTORY:
144
+ {full_text}
145
+
146
+ TASK:
147
+ Coach this student based on the 8-Step Story Arc.
148
+
149
+ REQUIRED STORY ARC:
150
+ 1. Executive Summary
151
+ 2. Data Description
152
+ 3. Targets & Metrics
153
+ 4. Model Candidates
154
+ 5. HPO Strategy
155
+ 6. Best Model Selection
156
+ 7. Validation
157
+ 8. Business Impact
158
+
159
+ INSTRUCTIONS:
160
+ 1. **Fill the Roadmap**: For each of the 8 steps above, determine status (✅, ⚠️, ❓, ⭕).
161
+ 2. **Slide Refs**: Cite specific slide numbers in the notes.
162
+ 3. **Tone**: Encouraging.
163
+ 4. **Summary**: Write a robust 2-paragraph summary (approx 150 words) explaining the overall impression and main areas for improvement.
164
+
165
+ OUTPUT JSON SCHEMA:
166
+ {{
167
+ "overall_summary": "Encouraging feedback (2 paragraphs).",
168
+ "structure_roadmap": [
169
+ {{
170
+ "step_name": "String (e.g. '1. Exec Summary')",
171
+ "status_icon": "String (✅, ⚠️, ❓, ⭕)",
172
+ "coach_notes": "String"
173
+ }}
174
+ ]
175
+ }}
176
+ """
177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  response = client.models.generate_content(
179
  model=MODEL_NAME,
180
  contents=prompt,
181
  config=types.GenerateContentConfig(response_mime_type="application/json")
182
  )
183
  print("DEBUG: Received Pass 2 Response from Gemini.")
184
+
185
+ critique = json.loads(response.text)
186
+
187
+ # Robustness: Handle list return from Coach
188
+ if isinstance(critique, list):
189
+ if len(critique) > 0 and isinstance(critique[0], dict):
190
+ critique = critique[0]
191
+ else:
192
+ # If it's a list but not a list of dicts, or empty, fail gracefully
193
+ raise ValueError(f"Coach returned a list, expected a dictionary. Output: {critique}")
194
+
195
+ return critique
196
 
197
  except Exception as e:
198
  print(f"CRITICAL ERROR in Pass 2: {e}")
199
  # Return a fallback critique so the UI doesn't hang
200
  return {
201
  "overall_summary": f"Error generating critique: {e}",
202
+ "structure_roadmap": [],
203
  "slide_tips": []
204
  }
205