Spaces:
Running
Running
| """Output formatting utilities for Gradio.""" | |
| import pandas as pd | |
| from typing import Dict, List, Any | |
| def format_overall_score(score: float) -> str: | |
| """Format overall score as HTML progress bar.""" | |
| score_int = int(round(score)) | |
| color = "#2ecc71" if score_int >= 70 else "#f39c12" if score_int >= 50 else "#e74c3c" | |
| return f""" | |
| <div style="padding:16px; background:#f8f9fa; border-radius:8px; text-align:center;"> | |
| <div style="font-size:14px; color:#666; margin-bottom:8px;">Overall Score</div> | |
| <div style="font-size:48px; font-weight:bold; color:{color};">{score_int}<span style="font-size:20px; color:#999;">/100</span></div> | |
| <div style="margin-top:8px; background:#ddd; border-radius:4px; height:20px; width:100%;"> | |
| <div style="background:{color}; width:{score_int}%; height:20px; border-radius:4px; transition:width 0.5s;"></div> | |
| </div> | |
| </div> | |
| """ | |
| def format_sub_scores(sub_scores: Dict[str, float]) -> pd.DataFrame: | |
| """Format sub-scores as a DataFrame for gr.BarPlot.""" | |
| df = pd.DataFrame({ | |
| "Sub-Score": list(sub_scores.keys()), | |
| "Score": list(sub_scores.values()) | |
| }) | |
| return df | |
| def format_strengths(strengths: List[str]) -> str: | |
| """Format strengths as HTML list.""" | |
| if not strengths: | |
| return "No notable strengths detected." | |
| items = "\n".join(f"<li>β {s}</li>" for s in strengths) | |
| return f"<ul style='margin:0; padding-left:20px;'>{items}</ul>" | |
| def format_weaknesses(weaknesses: List[str]) -> str: | |
| """Format weaknesses as HTML list.""" | |
| if not weaknesses: | |
| return "No notable weaknesses detected." | |
| items = "\n".join(f"<li>β οΈ {w}</li>" for w in weaknesses) | |
| return f"<ul style='margin:0; padding-left:20px;'>{items}</ul>" | |
| def format_suggestions(suggestions: List[Dict[str, Any]]) -> str: | |
| """Format suggestions as numbered HTML list.""" | |
| if not suggestions: | |
| return "No specific suggestions β your image scores well across all dimensions." | |
| items = [] | |
| for i, s in enumerate(suggestions[:5], 1): | |
| priority_emoji = {1: "π΄", 2: "π‘", 3: "π‘"}.get(i, "π’") | |
| items.append( | |
| f"<div style='margin-bottom:12px; padding:10px; background:#f0f4ff; border-radius:6px; border-left:4px solid #4a86e8;'>"> | |
| f"<b>{priority_emoji} Priority {i}</b> β {s['sub_score_target']}<br/>" | |
| f"<div style='margin-top:6px; color:#333;'>{s['message']}</div>" | |
| f"<div style='margin-top:4px; font-size:12px; color:#888;'>π Projected gain: +{s['projected_gain']:.0f} points</div>" | |
| f"</div>" | |
| ) | |
| return "\n".join(items) | |
| def format_projected_improvement(current: float, projected: float) -> str: | |
| """Format projected improvement as HTML.""" | |
| delta = projected - current | |
| if delta <= 0: | |
| return "<div style='padding:12px; background:#e8f5e9; border-radius:6px;'>π This image is already well-optimized!</div>" | |
| return f""" | |
| <div style="padding:12px; background:#fff3e0; border-radius:6px;"> | |
| <b>π‘ Projected Improvement</b><br/> | |
| Current: <b>{current:.0f}</b>/100 → After suggestions: <b>{projected:.0f}</b>/100 | |
| <span style="color:#e65100;"> (+{delta:.0f} points)</span> | |
| </div> | |
| """ | |
| def format_comparison(original: Dict[str, Any], revised: Dict[str, Any], | |
| improvements: List, regressions: List, | |
| next_steps: List[Dict[str, Any]]) -> str: | |
| """Format comparison results as HTML.""" | |
| orig_score = original.get("overall_score", 0) | |
| rev_score = revised.get("overall_score", 0) | |
| delta = rev_score - orig_score | |
| result = f""" | |
| <div style="padding:16px; background:#f8f9fa; border-radius:8px;"> | |
| <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:16px;"> | |
| <div style="text-align:center;"> | |
| <div style="font-size:12px; color:#666;">Original</div> | |
| <div style="font-size:32px; font-weight:bold; color:#e74c3c;">{orig_score:.0f}</div> | |
| </div> | |
| <div style="font-size:24px;">→</div> | |
| <div style="text-align:center;"> | |
| <div style="font-size:12px; color:#666;">Revised</div> | |
| <div style="font-size:32px; font-weight:bold; color:#2ecc71;">{rev_score:.0f}</div> | |
| </div> | |
| </div> | |
| """ | |
| if delta > 0: | |
| result += f"<div style='text-align:center; color:#27ae60; font-weight:bold; margin-bottom:12px;'>π Overall improved by +{delta:.0f} points</div>" | |
| elif delta < 0: | |
| result += f"<div style='text-align:center; color:#e74c3c; font-weight:bold; margin-bottom:12px;'>π Overall decreased by {delta:.0f} points</div>" | |
| else: | |
| result += "<div style='text-align:center; color:#666; margin-bottom:12px;'>Overall score unchanged</div>" | |
| if improvements: | |
| result += "<div style='font-weight:bold; color:#27ae60; margin-top:12px;'>β Improvements:</div><ul>" | |
| for name, val in improvements[:5]: | |
| result += f"<li>{name}: +{val:.0f} points</li>" | |
| result += "</ul>" | |
| if regressions: | |
| result += "<div style='font-weight:bold; color:#e74c3c; margin-top:12px;'>β οΈ Regressions:</div><ul>" | |
| for name, val in regressions[:5]: | |
| result += f"<li>{name}: {val:.0f} points</li>" | |
| result += "</ul>" | |
| if next_steps: | |
| result += "<div style='font-weight:bold; margin-top:12px;'>π Next Recommended Edits:</div>" | |
| for step in next_steps[:3]: | |
| result += f"<div style='margin:4px 0; padding:8px; background:#e3f2fd; border-radius:4px;'>{step['message']}</div>" | |
| result += "</div>" | |
| return result | |