lanna_lalala;- commited on
Commit
5b4001f
·
1 Parent(s): b413450
Files changed (1) hide show
  1. phase/Student_view/lesson.py +48 -21
phase/Student_view/lesson.py CHANGED
@@ -119,9 +119,37 @@ MODULES_META: Dict[str, List[Dict[str, Any]]] = {
119
 
120
  # Helper to read topic titles regardless of whether metadata uses `topics` or `topic_labels`
121
 
122
- def _topic_titles(level: str, module_id: int) -> List[str]:
 
 
 
 
 
 
 
123
  mod = next(m for m in MODULES_META[level] if m["id"] == module_id)
124
- return (mod.get("topics") or mod.get("topic_labels") or [])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
  # ---------------------------------------------
127
  # Backend integrations
@@ -132,10 +160,12 @@ def _fetch_topic_from_backend(level: str, module_id: int, topic_idx: int) -> Tup
132
  Calls the backend to read the topic text from the lessons folder.
133
  Returns (title, content). Title uses the configured UI label as a fallback.
134
  """
135
- # Human-friendly strings for the backend schema
 
 
136
  lesson_label = MODULES_META[level][[m["id"] for m in MODULES_META[level]].index(module_id)]["title"]
137
- module_label = str(module_id) # backend extracts digits from this string
138
- topic_label = str(topic_idx + 1)
139
 
140
  payload = {"lesson": lesson_label, "module": module_label, "topic": topic_label}
141
 
@@ -232,13 +262,13 @@ def _render_catalog():
232
  st.header("Financial Education")
233
  st.caption("Build your financial knowledge with structured paths for every skill level.")
234
 
235
- level = st.segmented_control(
236
- "Level",
237
- options=["beginner", "intermediate", "advanced"],
238
- default=st.session_state.level,
239
- format_func=lambda s: s.capitalize(),
240
- key="level",
241
- )
242
 
243
  cols = st.columns(3)
244
  for i, mod in enumerate(MODULES_META[level]):
@@ -248,7 +278,7 @@ def _render_catalog():
248
  st.caption(mod["description"])
249
  st.caption(f"Duration: {mod.get('duration','—')} · Difficulty: {mod.get('difficulty','—')}")
250
  with st.expander("Topics include"):
251
- for t in (mod.get("topics") or [])[:3]:
252
  st.write("• ", t)
253
  if st.button("Start Learning", key=f"start_{level}_{mod['id']}"):
254
  st.session_state.module_id = mod["id"]
@@ -259,18 +289,14 @@ def _render_catalog():
259
 
260
 
261
  def _get_topics(level: str, module_id: int) -> List[Tuple[str, str]]:
262
- """Load and cache all available topics for a module by probing sequentially."""
263
  cache_key = (level, module_id)
264
  if cache_key in st.session_state.topics_cache:
265
  return st.session_state.topics_cache[cache_key]
266
 
267
- # Probe up to N topics — stop on first 2 consecutive misses to keep it snappy
268
- out: List[Tuple[str, str]] = []
269
  misses = 0
270
- # Prefer the UI labels count; probe a little beyond in case backend has more
271
- planned = len(_topic_titles(level, module_id)) + 2
272
- N = max(3, planned)
273
- for idx in range(N):
274
  title, text = _fetch_topic_from_backend(level, module_id, idx)
275
  if text and not text.startswith("(Failed"):
276
  out.append((title, text))
@@ -279,11 +305,12 @@ def _get_topics(level: str, module_id: int) -> List[Tuple[str, str]]:
279
  misses += 1
280
  if misses >= 2:
281
  break
282
- # Cache
283
  st.session_state.topics_cache[cache_key] = out
284
  return out
285
 
286
 
 
287
  def _render_lesson():
288
  level = st.session_state.level
289
  module_id = st.session_state.module_id
 
119
 
120
  # Helper to read topic titles regardless of whether metadata uses `topics` or `topic_labels`
121
 
122
+ def _topic_plan(level: str, module_id: int):
123
+ """
124
+ Returns a list of (title, backend_ordinal) after filtering:
125
+ - drop any 'Play:' topic
126
+ - drop 'Quiz'
127
+ - keep first five + the Summary (6 total)
128
+ backend_ordinal is the 1-based index in the original metadata (so backend files line up).
129
+ """
130
  mod = next(m for m in MODULES_META[level] if m["id"] == module_id)
131
+ raw = (mod.get("topics") or mod.get("topic_labels") or [])
132
+ plan = []
133
+ for i, t in enumerate(raw, start=1):
134
+ tl = t.strip().lower()
135
+ if tl == "quiz" or tl.startswith("play:"):
136
+ continue
137
+ plan.append((t, i))
138
+
139
+ # Ensure at most 6 topics: first five + Summary if present
140
+ if len(plan) > 6:
141
+ # Prefer keeping a 'Summary' entry last if it exists
142
+ summary_pos = next((idx for idx, (title, _) in enumerate(plan)
143
+ if title.strip().lower().startswith("summary")), None)
144
+ if summary_pos is not None:
145
+ plan = plan[:5] + [plan[summary_pos]]
146
+ else:
147
+ plan = plan[:6]
148
+ return plan
149
+
150
+ def _topic_titles(level: str, module_id: int):
151
+ return [t for (t, _) in _topic_plan(level, module_id)]
152
+
153
 
154
  # ---------------------------------------------
155
  # Backend integrations
 
160
  Calls the backend to read the topic text from the lessons folder.
161
  Returns (title, content). Title uses the configured UI label as a fallback.
162
  """
163
+ plan = _topic_plan(level, module_id)
164
+ title, backend_ordinal = plan[topic_idx] # 1-based ordinal in original list
165
+ # this keeps your filesystem mapping correct: topic_{backend_ordinal}.txt
166
  lesson_label = MODULES_META[level][[m["id"] for m in MODULES_META[level]].index(module_id)]["title"]
167
+ module_label = str(module_id)
168
+ topic_label = str(backend_ordinal)
169
 
170
  payload = {"lesson": lesson_label, "module": module_label, "topic": topic_label}
171
 
 
262
  st.header("Financial Education")
263
  st.caption("Build your financial knowledge with structured paths for every skill level.")
264
 
265
+ # level = st.segmented_control(
266
+ # "Level",
267
+ # options=["beginner", "intermediate", "advanced"],
268
+ # default=st.session_state.level,
269
+ # format_func=lambda s: s.capitalize(),
270
+ # key="level",
271
+ # )
272
 
273
  cols = st.columns(3)
274
  for i, mod in enumerate(MODULES_META[level]):
 
278
  st.caption(mod["description"])
279
  st.caption(f"Duration: {mod.get('duration','—')} · Difficulty: {mod.get('difficulty','—')}")
280
  with st.expander("Topics include"):
281
+ for t, _ord in _topic_plan(level, mod["id"]):
282
  st.write("• ", t)
283
  if st.button("Start Learning", key=f"start_{level}_{mod['id']}"):
284
  st.session_state.module_id = mod["id"]
 
289
 
290
 
291
  def _get_topics(level: str, module_id: int) -> List[Tuple[str, str]]:
 
292
  cache_key = (level, module_id)
293
  if cache_key in st.session_state.topics_cache:
294
  return st.session_state.topics_cache[cache_key]
295
 
296
+ plan = _topic_plan(level, module_id)
297
+ out = []
298
  misses = 0
299
+ for idx in range(len(plan)): # exactly the filtered six
 
 
 
300
  title, text = _fetch_topic_from_backend(level, module_id, idx)
301
  if text and not text.startswith("(Failed"):
302
  out.append((title, text))
 
305
  misses += 1
306
  if misses >= 2:
307
  break
308
+
309
  st.session_state.topics_cache[cache_key] = out
310
  return out
311
 
312
 
313
+
314
  def _render_lesson():
315
  level = st.session_state.level
316
  module_id = st.session_state.module_id