Update app.py
Browse files
app.py
CHANGED
|
@@ -33,10 +33,9 @@ emotion_tokenizer = AutoTokenizer.from_pretrained(emotion_model_name)
|
|
| 33 |
emotion_model = AutoModelForSequenceClassification.from_pretrained(emotion_model_name)
|
| 34 |
|
| 35 |
# ---------- constants ----------
|
| 36 |
-
CSV_PATH_PLUS = "la matrice plus.csv" # pathways + colors +
|
| 37 |
CSV_PATH_COLOR = "la matrice.csv" # color lexicon
|
| 38 |
|
| 39 |
-
# only explicit pathways (no Auto here)
|
| 40 |
SEQUENCE_ALIASES = {
|
| 41 |
"Direct": "direct",
|
| 42 |
"Fem": "feminine",
|
|
@@ -99,7 +98,7 @@ GNH_COLORS: Dict[str, str] = {
|
|
| 99 |
"Cultural Diversity": "#9370db",
|
| 100 |
}
|
| 101 |
|
| 102 |
-
# ---------- load pathway → colors & phrase
|
| 103 |
def load_pathway_info(csv_path_plus: str):
|
| 104 |
df = pd.read_csv(csv_path_plus)
|
| 105 |
keys = set(SEQUENCE_ALIASES.values())
|
|
@@ -111,10 +110,10 @@ def load_pathway_info(csv_path_plus: str):
|
|
| 111 |
cols_for_phrase = [c for c in df.columns if c not in ("color", "r", "g", "b")]
|
| 112 |
for _, row in rows.iterrows():
|
| 113 |
key = str(row["color"]).strip().lower()
|
| 114 |
-
# colors
|
| 115 |
colors_field = str(row.get("r", "") or "")
|
| 116 |
colors = [c.strip().lower() for c in re.split(r"[,\s]+", colors_field) if c.strip()]
|
| 117 |
-
seq_to_colors[key] = list(dict.fromkeys(colors)) # dedupe
|
| 118 |
|
| 119 |
vals = []
|
| 120 |
for c in cols_for_phrase:
|
|
@@ -130,7 +129,7 @@ def load_pathway_info(csv_path_plus: str):
|
|
| 130 |
|
| 131 |
SEQ_TO_COLORS, SEQ_PHRASE = load_pathway_info(CSV_PATH_PLUS)
|
| 132 |
|
| 133 |
-
# ---------- load color lexicon
|
| 134 |
def _find_col(df: pd.DataFrame, candidates: List[str]) -> str | None:
|
| 135 |
names = {c.lower(): c for c in df.columns}
|
| 136 |
for c in candidates:
|
|
@@ -247,7 +246,7 @@ def chip_html_for(color: str, mode: str, max_words: int = 4) -> str:
|
|
| 247 |
dot = f"<span style='display:inline-block;width:12px;height:12px;border-radius:50%;background:{hex_color};margin-right:6px;border:1px solid #999;vertical-align:middle'></span>"
|
| 248 |
pill = f"<span style='display:inline-block;margin:2px 6px;padding:2px 8px;border-radius:12px;background:#eee;font-size:12px'>{domain} · {sim:.2f}</span>"
|
| 249 |
return f"<div style='margin-bottom:6px'>{dot}<b>{color.capitalize()}</b>{pill}</div>"
|
| 250 |
-
#
|
| 251 |
key = "english" if mode.lower() == "english" else ("matrice1" if mode.lower()=="matrice1" else "matrice")
|
| 252 |
words = COLOR_LEX.get(color.lower(), {}).get(key, [])[:max_words]
|
| 253 |
pills = "".join(
|
|
@@ -270,23 +269,22 @@ def labels_for_mode(colors: List[str], mode: str) -> List[str]:
|
|
| 270 |
return [c.capitalize() for c in colors]
|
| 271 |
|
| 272 |
# ---------- dynamic prompt UI (2–8 inputs) ----------
|
| 273 |
-
MAX_COLORS = 8 # upper bound
|
| 274 |
|
| 275 |
def update_prompt_ui(seq_choice: str, word_mode: str):
|
| 276 |
key = SEQUENCE_ALIASES.get(seq_choice)
|
| 277 |
colors = colors_for_sequence(key)
|
| 278 |
labels = labels_for_mode(colors, word_mode)
|
| 279 |
|
| 280 |
-
# chips HTML for all colors
|
| 281 |
chips = "".join(chip_html_for(c, word_mode) for c in colors) or "No prompts available for this pathway."
|
| 282 |
|
| 283 |
-
#
|
| 284 |
inputs_updates = []
|
| 285 |
for i in range(MAX_COLORS):
|
| 286 |
if i < len(colors):
|
| 287 |
-
lab =
|
| 288 |
-
ph = f"Describe {
|
| 289 |
-
inputs_updates.append(gr.update(visible=True, label=lab, placeholder=ph, value=""))
|
| 290 |
else:
|
| 291 |
inputs_updates.append(gr.update(visible=False, value="", label=f"Input {i+1}", placeholder="—"))
|
| 292 |
return (chips, *inputs_updates)
|
|
@@ -295,14 +293,14 @@ def update_prompt_ui(seq_choice: str, word_mode: str):
|
|
| 295 |
def analyze(text: str, seq_choice: str, word_mode: str, *color_inputs):
|
| 296 |
"""
|
| 297 |
- user chooses pathway
|
| 298 |
-
-
|
| 299 |
-
- compose updated pathway phrase
|
| 300 |
- analyze sentiment/emotion + GNH on (text + updated phrase)
|
| 301 |
"""
|
| 302 |
key = SEQUENCE_ALIASES.get(seq_choice)
|
| 303 |
if key not in SEQ_PHRASE:
|
| 304 |
return (5.0, "neutral (0.0)", 5.0, "Please choose a valid pathway.", "{}", None, None,
|
| 305 |
-
f"{seq_choice} (unavailable)")
|
| 306 |
|
| 307 |
sentiment = score_sentiment(text or "")
|
| 308 |
emotion, emo_conf = classify_emotion(text or "")
|
|
@@ -311,7 +309,7 @@ def analyze(text: str, seq_choice: str, word_mode: str, *color_inputs):
|
|
| 311 |
colors = colors_for_sequence(key)
|
| 312 |
labels = labels_for_mode(colors, word_mode)
|
| 313 |
|
| 314 |
-
#
|
| 315 |
base_phrase = SEQ_PHRASE.get(key, "")
|
| 316 |
pieces = [base_phrase]
|
| 317 |
for lab, user_text in zip(labels, list(color_inputs)[:len(colors)]):
|
|
@@ -330,7 +328,7 @@ def analyze(text: str, seq_choice: str, word_mode: str, *color_inputs):
|
|
| 330 |
meta = f"{key} | colors: {', '.join(cols) if cols else '—'}"
|
| 331 |
img_path = sequence_to_image_path(key)
|
| 332 |
|
| 333 |
-
#
|
| 334 |
chips_and_inputs = update_prompt_ui(seq_choice, word_mode)
|
| 335 |
|
| 336 |
return (
|
|
@@ -353,7 +351,7 @@ with gr.Blocks(title="RGB Root Matriz Color Plotter") as demo:
|
|
| 353 |
|
| 354 |
with gr.Row():
|
| 355 |
seq = gr.Dropdown(choices=SEQ_CHOICES, value=DEFAULT_SEQ, label="Pathway")
|
| 356 |
-
word_mode = gr.Radio(choices=
|
| 357 |
|
| 358 |
chips_block = gr.HTML() # chips for all colors
|
| 359 |
|
|
@@ -379,13 +377,7 @@ with gr.Blocks(title="RGB Root Matriz Color Plotter") as demo:
|
|
| 379 |
img_out = gr.Image(label="Pathway image", type="filepath")
|
| 380 |
meta_out = gr.Text(label="Chosen pathway / colors")
|
| 381 |
|
| 382 |
-
#
|
| 383 |
-
init_updates = update_prompt_ui(DEFAULT_SEQ, "Matrice1")
|
| 384 |
-
chips_block.value = init_updates[0]
|
| 385 |
-
for tb, up in zip(color_inputs, init_updates[1:1+MAX_COLORS]):
|
| 386 |
-
tb.update(**up)
|
| 387 |
-
|
| 388 |
-
# re-render prompts on changes
|
| 389 |
def _update_ui(seq_choice, mode):
|
| 390 |
return update_prompt_ui(seq_choice, mode)
|
| 391 |
|
|
@@ -398,7 +390,12 @@ with gr.Blocks(title="RGB Root Matriz Color Plotter") as demo:
|
|
| 398 |
outputs=[sent, emo, acc, phrase_out, gnh_top, gnh_plot, img_out, meta_out, chips_block, *color_inputs],
|
| 399 |
)
|
| 400 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 401 |
if __name__ == "__main__":
|
| 402 |
demo.launch()
|
| 403 |
-
|
| 404 |
-
|
|
|
|
| 33 |
emotion_model = AutoModelForSequenceClassification.from_pretrained(emotion_model_name)
|
| 34 |
|
| 35 |
# ---------- constants ----------
|
| 36 |
+
CSV_PATH_PLUS = "la matrice plus.csv" # pathways + colors + phrase parts
|
| 37 |
CSV_PATH_COLOR = "la matrice.csv" # color lexicon
|
| 38 |
|
|
|
|
| 39 |
SEQUENCE_ALIASES = {
|
| 40 |
"Direct": "direct",
|
| 41 |
"Fem": "feminine",
|
|
|
|
| 98 |
"Cultural Diversity": "#9370db",
|
| 99 |
}
|
| 100 |
|
| 101 |
+
# ---------- load pathway → colors & phrase ----------
|
| 102 |
def load_pathway_info(csv_path_plus: str):
|
| 103 |
df = pd.read_csv(csv_path_plus)
|
| 104 |
keys = set(SEQUENCE_ALIASES.values())
|
|
|
|
| 110 |
cols_for_phrase = [c for c in df.columns if c not in ("color", "r", "g", "b")]
|
| 111 |
for _, row in rows.iterrows():
|
| 112 |
key = str(row["color"]).strip().lower()
|
| 113 |
+
# colors in 'r' as comma/space separated list (supports 2–8)
|
| 114 |
colors_field = str(row.get("r", "") or "")
|
| 115 |
colors = [c.strip().lower() for c in re.split(r"[,\s]+", colors_field) if c.strip()]
|
| 116 |
+
seq_to_colors[key] = list(dict.fromkeys(colors)) # dedupe
|
| 117 |
|
| 118 |
vals = []
|
| 119 |
for c in cols_for_phrase:
|
|
|
|
| 129 |
|
| 130 |
SEQ_TO_COLORS, SEQ_PHRASE = load_pathway_info(CSV_PATH_PLUS)
|
| 131 |
|
| 132 |
+
# ---------- load color lexicon ----------
|
| 133 |
def _find_col(df: pd.DataFrame, candidates: List[str]) -> str | None:
|
| 134 |
names = {c.lower(): c for c in df.columns}
|
| 135 |
for c in candidates:
|
|
|
|
| 246 |
dot = f"<span style='display:inline-block;width:12px;height:12px;border-radius:50%;background:{hex_color};margin-right:6px;border:1px solid #999;vertical-align:middle'></span>"
|
| 247 |
pill = f"<span style='display:inline-block;margin:2px 6px;padding:2px 8px;border-radius:12px;background:#eee;font-size:12px'>{domain} · {sim:.2f}</span>"
|
| 248 |
return f"<div style='margin-bottom:6px'>{dot}<b>{color.capitalize()}</b>{pill}</div>"
|
| 249 |
+
# lexicon modes
|
| 250 |
key = "english" if mode.lower() == "english" else ("matrice1" if mode.lower()=="matrice1" else "matrice")
|
| 251 |
words = COLOR_LEX.get(color.lower(), {}).get(key, [])[:max_words]
|
| 252 |
pills = "".join(
|
|
|
|
| 269 |
return [c.capitalize() for c in colors]
|
| 270 |
|
| 271 |
# ---------- dynamic prompt UI (2–8 inputs) ----------
|
| 272 |
+
MAX_COLORS = 8 # upper bound; raise if some pathways exceed this
|
| 273 |
|
| 274 |
def update_prompt_ui(seq_choice: str, word_mode: str):
|
| 275 |
key = SEQUENCE_ALIASES.get(seq_choice)
|
| 276 |
colors = colors_for_sequence(key)
|
| 277 |
labels = labels_for_mode(colors, word_mode)
|
| 278 |
|
|
|
|
| 279 |
chips = "".join(chip_html_for(c, word_mode) for c in colors) or "No prompts available for this pathway."
|
| 280 |
|
| 281 |
+
# Return updates for chips + each color input (visibility, label, placeholder)
|
| 282 |
inputs_updates = []
|
| 283 |
for i in range(MAX_COLORS):
|
| 284 |
if i < len(colors):
|
| 285 |
+
lab = labels[i] if i < len(labels) else f"Input {i+1}"
|
| 286 |
+
ph = f"Describe {lab} meaning..." if lab else "—"
|
| 287 |
+
inputs_updates.append(gr.update(visible=True, label=f"{lab} meaning", placeholder=ph, value=""))
|
| 288 |
else:
|
| 289 |
inputs_updates.append(gr.update(visible=False, value="", label=f"Input {i+1}", placeholder="—"))
|
| 290 |
return (chips, *inputs_updates)
|
|
|
|
| 293 |
def analyze(text: str, seq_choice: str, word_mode: str, *color_inputs):
|
| 294 |
"""
|
| 295 |
- user chooses pathway
|
| 296 |
+
- show N color prompts (2–8)
|
| 297 |
+
- compose updated pathway phrase embedding all inputs
|
| 298 |
- analyze sentiment/emotion + GNH on (text + updated phrase)
|
| 299 |
"""
|
| 300 |
key = SEQUENCE_ALIASES.get(seq_choice)
|
| 301 |
if key not in SEQ_PHRASE:
|
| 302 |
return (5.0, "neutral (0.0)", 5.0, "Please choose a valid pathway.", "{}", None, None,
|
| 303 |
+
f"{seq_choice} (unavailable)", *update_prompt_ui(seq_choice, word_mode))
|
| 304 |
|
| 305 |
sentiment = score_sentiment(text or "")
|
| 306 |
emotion, emo_conf = classify_emotion(text or "")
|
|
|
|
| 309 |
colors = colors_for_sequence(key)
|
| 310 |
labels = labels_for_mode(colors, word_mode)
|
| 311 |
|
| 312 |
+
# Updated phrase = base phrase + each "{Label}: {input}"
|
| 313 |
base_phrase = SEQ_PHRASE.get(key, "")
|
| 314 |
pieces = [base_phrase]
|
| 315 |
for lab, user_text in zip(labels, list(color_inputs)[:len(colors)]):
|
|
|
|
| 328 |
meta = f"{key} | colors: {', '.join(cols) if cols else '—'}"
|
| 329 |
img_path = sequence_to_image_path(key)
|
| 330 |
|
| 331 |
+
# keep UI prompts in sync after run
|
| 332 |
chips_and_inputs = update_prompt_ui(seq_choice, word_mode)
|
| 333 |
|
| 334 |
return (
|
|
|
|
| 351 |
|
| 352 |
with gr.Row():
|
| 353 |
seq = gr.Dropdown(choices=SEQ_CHOICES, value=DEFAULT_SEQ, label="Pathway")
|
| 354 |
+
word_mode = gr.Radio(choices=WORD_MODES, value="Matrice1", label="Word Mode")
|
| 355 |
|
| 356 |
chips_block = gr.HTML() # chips for all colors
|
| 357 |
|
|
|
|
| 377 |
img_out = gr.Image(label="Pathway image", type="filepath")
|
| 378 |
meta_out = gr.Text(label="Chosen pathway / colors")
|
| 379 |
|
| 380 |
+
# events
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 381 |
def _update_ui(seq_choice, mode):
|
| 382 |
return update_prompt_ui(seq_choice, mode)
|
| 383 |
|
|
|
|
| 390 |
outputs=[sent, emo, acc, phrase_out, gnh_top, gnh_plot, img_out, meta_out, chips_block, *color_inputs],
|
| 391 |
)
|
| 392 |
|
| 393 |
+
# ✅ initialize prompts on load (instead of tb.update(...))
|
| 394 |
+
demo.load(
|
| 395 |
+
fn=_update_ui,
|
| 396 |
+
inputs=[seq, word_mode],
|
| 397 |
+
outputs=[chips_block, *color_inputs]
|
| 398 |
+
)
|
| 399 |
+
|
| 400 |
if __name__ == "__main__":
|
| 401 |
demo.launch()
|
|
|
|
|
|