Spaces:
Paused
Paused
UI: hide performance score and Practice Tips; keep functions. Prompt: update Strengths/Areas/Practice Tips instructions.
Browse files- .gitignore +3 -0
- app/models/llm_analyzer.py +17 -121
.gitignore
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
downloads/*.mov
|
| 2 |
+
*.pkl
|
| 3 |
+
*.faiss
|
app/models/llm_analyzer.py
CHANGED
|
@@ -533,12 +533,10 @@ Use the benchmarks above to guide your evaluation. Follow this exact format:
|
|
| 533 |
|
| 534 |
**Strengths**
|
| 535 |
|
| 536 |
-
|
| 537 |
-
-
|
| 538 |
-
-
|
| 539 |
-
- Compare to
|
| 540 |
-
- Highlight what's working well and the benefit
|
| 541 |
-
- Use supportive tone
|
| 542 |
|
| 543 |
Example:
|
| 544 |
1. Arm Extension:
|
|
@@ -546,25 +544,23 @@ Excellent extension at impact, this maintains a wide swing arc, just like elite
|
|
| 546 |
|
| 547 |
**Areas for Improvement**
|
| 548 |
|
| 549 |
-
|
| 550 |
-
-
|
| 551 |
-
-
|
| 552 |
-
- Follow with explanation of impact and drill suggestion
|
| 553 |
-
- Focus on what needs work and why
|
| 554 |
|
| 555 |
Example:
|
| 556 |
-
1. Hip Rotation —
|
| 557 |
-
|
| 558 |
|
| 559 |
**Practice Tips**
|
| 560 |
|
| 561 |
-
|
| 562 |
-
-
|
| 563 |
-
-
|
| 564 |
-
- Be easy to understand and practice
|
| 565 |
|
| 566 |
Example:
|
| 567 |
-
1. Ground Force Timing:
|
|
|
|
| 568 |
|
| 569 |
**SCORING GUIDELINES (Use to help decide % score)**
|
| 570 |
|
|
@@ -591,7 +587,7 @@ Example:
|
|
| 591 |
**STYLE & FORMATTING RULES:**
|
| 592 |
- Use these headers: PERFORMANCE_CLASSIFICATION, Strengths, Areas for Improvement, Practice Tips
|
| 593 |
- No emojis anywhere in the response
|
| 594 |
-
-
|
| 595 |
- Use numbered lists (1-3) for each section
|
| 596 |
- Tie all points to professional standards
|
| 597 |
- Use a positive, coaching tone throughout
|
|
@@ -841,90 +837,9 @@ def display_formatted_analysis(analysis_data):
|
|
| 841 |
Args:
|
| 842 |
analysis_data (dict): Structured analysis data from parse_and_format_analysis
|
| 843 |
"""
|
| 844 |
-
# 1. Performance
|
| 845 |
user_percentage = analysis_data['classification']
|
| 846 |
|
| 847 |
-
# Display classification in black bolded header
|
| 848 |
-
st.markdown(f"""
|
| 849 |
-
<h2 style='color: black; font-weight: bold; text-align: center; margin-bottom: 20px;'>
|
| 850 |
-
Performance Score: {user_percentage}%
|
| 851 |
-
</h2>
|
| 852 |
-
""", unsafe_allow_html=True)
|
| 853 |
-
|
| 854 |
-
# Create a visual progress bar
|
| 855 |
-
progress_color = "#ff4444" # Red for low scores
|
| 856 |
-
if user_percentage >= 80:
|
| 857 |
-
progress_color = "#44aa44" # Green for high scores
|
| 858 |
-
elif user_percentage >= 60:
|
| 859 |
-
progress_color = "#ffdd00" # Yellow for good scores
|
| 860 |
-
elif user_percentage >= 40:
|
| 861 |
-
progress_color = "#ff8800" # Orange for medium scores
|
| 862 |
-
|
| 863 |
-
# Progress bar with percentage labels
|
| 864 |
-
st.markdown(f"""
|
| 865 |
-
<div style='margin: 20px 0;'>
|
| 866 |
-
<div style='display: flex; justify-content: space-between; font-size: 12px; color: #666; margin-bottom: 5px;'>
|
| 867 |
-
<span>10% - Complete Beginner</span>
|
| 868 |
-
<span>50% - Intermediate</span>
|
| 869 |
-
<span>100% - Professional</span>
|
| 870 |
-
</div>
|
| 871 |
-
<div style='width: 100%; background-color: #f0f0f0; border-radius: 25px; height: 30px; position: relative;'>
|
| 872 |
-
<div style='width: {user_percentage}%; background-color: {progress_color}; height: 30px; border-radius: 25px;
|
| 873 |
-
display: flex; align-items: center; justify-content: center; color: white; font-weight: bold;'>
|
| 874 |
-
{user_percentage}%
|
| 875 |
-
</div>
|
| 876 |
-
</div>
|
| 877 |
-
<div style='display: flex; justify-content: space-between; font-size: 10px; color: #888; margin-top: 5px;'>
|
| 878 |
-
<span>10%</span>
|
| 879 |
-
<span>20%</span>
|
| 880 |
-
<span>30%</span>
|
| 881 |
-
<span>40%</span>
|
| 882 |
-
<span>50%</span>
|
| 883 |
-
<span>60%</span>
|
| 884 |
-
<span>70%</span>
|
| 885 |
-
<span>80%</span>
|
| 886 |
-
<span>90%</span>
|
| 887 |
-
<span>100%</span>
|
| 888 |
-
</div>
|
| 889 |
-
</div>
|
| 890 |
-
""", unsafe_allow_html=True)
|
| 891 |
-
|
| 892 |
-
# Performance level description based on percentage
|
| 893 |
-
if user_percentage >= 90:
|
| 894 |
-
level_desc = "🏆 **Professional/Tour Level** - Consistently meets or exceeds professional benchmarks"
|
| 895 |
-
level_color = "#44aa44"
|
| 896 |
-
elif user_percentage >= 80:
|
| 897 |
-
level_desc = "🥇 **Advanced Amateur** - Meets most professional standards with minor gaps"
|
| 898 |
-
level_color = "#66bb44"
|
| 899 |
-
elif user_percentage >= 70:
|
| 900 |
-
level_desc = "🥈 **Skilled Amateur** - Solid fundamentals with some gaps from professional standards"
|
| 901 |
-
level_color = "#88cc44"
|
| 902 |
-
elif user_percentage >= 60:
|
| 903 |
-
level_desc = "🥉 **Intermediate** - Good basic mechanics but several areas need improvement"
|
| 904 |
-
level_color = "#ffdd00"
|
| 905 |
-
elif user_percentage >= 50:
|
| 906 |
-
level_desc = "📈 **Developing Intermediate** - Basic swing structure present"
|
| 907 |
-
level_color = "#ffcc00"
|
| 908 |
-
elif user_percentage >= 40:
|
| 909 |
-
level_desc = "📚 **Advanced Beginner** - Some fundamentals in place"
|
| 910 |
-
level_color = "#ff8800"
|
| 911 |
-
elif user_percentage >= 30:
|
| 912 |
-
level_desc = "🎯 **Beginner** - Basic swing motion present but major improvements needed"
|
| 913 |
-
level_color = "#ff6600"
|
| 914 |
-
elif user_percentage >= 20:
|
| 915 |
-
level_desc = "🌱 **Novice** - Limited swing fundamentals, extensive work needed"
|
| 916 |
-
level_color = "#ff4444"
|
| 917 |
-
else:
|
| 918 |
-
level_desc = "🚀 **Complete Beginner** - Minimal swing structure, needs comprehensive fundamental development"
|
| 919 |
-
level_color = "#ff2222"
|
| 920 |
-
|
| 921 |
-
st.markdown(f"""
|
| 922 |
-
<div style='text-align: center; padding: 15px; background-color: {level_color}20;
|
| 923 |
-
border-radius: 10px; margin: 20px 0; border: 2px solid {level_color};'>
|
| 924 |
-
<div style='color: {level_color}; font-size: 16px; font-weight: bold;'>{level_desc}</div>
|
| 925 |
-
</div>
|
| 926 |
-
""", unsafe_allow_html=True)
|
| 927 |
-
|
| 928 |
st.markdown("---")
|
| 929 |
|
| 930 |
# 2. Strengths and Weaknesses Table
|
|
@@ -964,26 +879,7 @@ def display_formatted_analysis(analysis_data):
|
|
| 964 |
st.markdown(f"{i}. {weakness}")
|
| 965 |
st.markdown("</div>", unsafe_allow_html=True)
|
| 966 |
|
| 967 |
-
|
| 968 |
-
|
| 969 |
-
# 3. Practice Tips
|
| 970 |
-
st.subheader("Practice Tips")
|
| 971 |
-
|
| 972 |
-
for priority in sorted(analysis_data['priority_improvements'], key=lambda x: x['rank']):
|
| 973 |
-
rank = priority['rank']
|
| 974 |
-
description = priority['description']
|
| 975 |
-
|
| 976 |
-
# For simple "Topic: Description" format, just display it cleanly
|
| 977 |
-
if ':' in description:
|
| 978 |
-
parts = description.split(':', 1)
|
| 979 |
-
topic = parts[0].strip()
|
| 980 |
-
desc = parts[1].strip()
|
| 981 |
-
st.markdown(f"**{rank}. {topic}:** {desc}")
|
| 982 |
-
else:
|
| 983 |
-
# Fallback for other formats
|
| 984 |
-
st.markdown(f"**{rank}. {description}**")
|
| 985 |
-
|
| 986 |
-
st.write("") # Add spacing between items
|
| 987 |
|
| 988 |
|
| 989 |
def calculate_biomechanical_metrics(pose_data, swing_phases):
|
|
|
|
| 533 |
|
| 534 |
**Strengths**
|
| 535 |
|
| 536 |
+
Write exactly 3 strengths, numbered 1–3. For each:
|
| 537 |
+
- Start with the topic name followed by a colon
|
| 538 |
+
- Write 1 short, positive sentence
|
| 539 |
+
- Compare to pro-level or elite standards
|
|
|
|
|
|
|
| 540 |
|
| 541 |
Example:
|
| 542 |
1. Arm Extension:
|
|
|
|
| 544 |
|
| 545 |
**Areas for Improvement**
|
| 546 |
|
| 547 |
+
Write exactly 3 areas for improvement, numbered 1–3. For each:
|
| 548 |
+
- Use format: Topic — Your metric, pro range
|
| 549 |
+
- Write 1 short sentence explaining the issue
|
|
|
|
|
|
|
| 550 |
|
| 551 |
Example:
|
| 552 |
+
1. Hip Rotation — 12.7°, pros range from 25–90°
|
| 553 |
+
Limited rotation reduces power and distance.
|
| 554 |
|
| 555 |
**Practice Tips**
|
| 556 |
|
| 557 |
+
Write exactly 3 practice tips, numbered 1–3. For each:
|
| 558 |
+
- Start with the topic name followed by “Drill:”
|
| 559 |
+
- Write 1 short sentence that describes what to practice
|
|
|
|
| 560 |
|
| 561 |
Example:
|
| 562 |
+
1. Ground Force Timing Drill:
|
| 563 |
+
Focus on pushing against the ground earlier in the downswing.
|
| 564 |
|
| 565 |
**SCORING GUIDELINES (Use to help decide % score)**
|
| 566 |
|
|
|
|
| 587 |
**STYLE & FORMATTING RULES:**
|
| 588 |
- Use these headers: PERFORMANCE_CLASSIFICATION, Strengths, Areas for Improvement, Practice Tips
|
| 589 |
- No emojis anywhere in the response
|
| 590 |
+
- Use an em dash in Areas for Improvement (Topic — metric), and colons elsewhere
|
| 591 |
- Use numbered lists (1-3) for each section
|
| 592 |
- Tie all points to professional standards
|
| 593 |
- Use a positive, coaching tone throughout
|
|
|
|
| 837 |
Args:
|
| 838 |
analysis_data (dict): Structured analysis data from parse_and_format_analysis
|
| 839 |
"""
|
| 840 |
+
# 1. Performance classification is kept for logic but hidden from the UI
|
| 841 |
user_percentage = analysis_data['classification']
|
| 842 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 843 |
st.markdown("---")
|
| 844 |
|
| 845 |
# 2. Strengths and Weaknesses Table
|
|
|
|
| 879 |
st.markdown(f"{i}. {weakness}")
|
| 880 |
st.markdown("</div>", unsafe_allow_html=True)
|
| 881 |
|
| 882 |
+
# Practice Tips are computed but intentionally not displayed in the UI
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 883 |
|
| 884 |
|
| 885 |
def calculate_biomechanical_metrics(pose_data, swing_phases):
|