chenemii commited on
Commit
2d71c32
·
1 Parent(s): e8f3c26
Files changed (1) hide show
  1. app/models/llm_analyzer.py +220 -186
app/models/llm_analyzer.py CHANGED
@@ -457,27 +457,35 @@ I've analyzed a golf swing and extracted the following data:
457
 
458
  ## ANALYSIS INSTRUCTIONS
459
 
460
- Using the professional benchmarks above as your calibration reference, provide:
461
-
462
- 1. **Performance Classification**: Start with "Performance Classification: [Professional/Advanced/Intermediate/Beginner]" based on how the player's metrics compare to professional standards.
463
-
464
- 2. **Comparative Analysis**:
465
- - **Strengths** (metrics that meet/exceed professional benchmarks):
466
- List specific strong points (use bullet points)
467
- Reference professional benchmark values
468
-
469
- - **Areas for Improvement** (metrics significantly below professional standards):
470
- List specific weaknesses (use bullet points)
471
- Note the gap from professional standards
472
-
473
- 3. **Priority Improvement Areas**: List exactly 3 areas in order of importance:
474
- 1. [Most Critical] - Describe what's wrong and what it should be like
475
- 2. [Important] - Describe what's wrong and what it should be like
476
- 3. [Focus Area] - Describe what's wrong and what it should be like
477
-
478
- Remember: Professional golfers consistently achieve the benchmark metrics shown above. Use these as the gold standard for what constitutes excellent golf swing mechanics, while being realistic about the progression needed to reach those levels.
479
-
480
- Provide your analysis in the structured format above for optimal coaching feedback.
 
 
 
 
 
 
 
 
481
  """
482
 
483
  return prompt
@@ -501,155 +509,154 @@ def parse_and_format_analysis(raw_analysis):
501
  'priority_improvements': []
502
  }
503
 
504
- # Try to extract classification from the analysis
505
- classification_patterns = [
506
- r'(?:Performance Classification|Classification|Level).*?:\s*(Professional|Advanced|Intermediate|Beginner)',
507
- r'(Professional|Advanced|Intermediate|Beginner)\s+(?:Level|Amateur)',
508
- r'classified as\s+(Professional|Advanced|Intermediate|Beginner)',
509
- r'(?:at|as)\s+(?:an?\s+)?(Professional|Advanced|Intermediate|Beginner)\s+level'
510
- ]
511
-
512
- classification_found = False
513
- for pattern in classification_patterns:
514
- match = re.search(pattern, raw_analysis, re.IGNORECASE)
515
- if match:
516
- formatted_analysis['classification'] = match.group(1).title()
517
- classification_found = True
518
- break
519
-
520
- # If no classification found, try to infer from content
521
- if not classification_found:
522
- analysis_lower = raw_analysis.lower()
523
- if 'professional' in analysis_lower and ('meets' in analysis_lower or 'exceeds' in analysis_lower):
524
- formatted_analysis['classification'] = 'Professional'
525
- elif 'advanced' in analysis_lower or ('within 10' in analysis_lower and 'pro' in analysis_lower):
526
- formatted_analysis['classification'] = 'Advanced'
527
- elif 'beginner' in analysis_lower or ('30%' in analysis_lower and 'below' in analysis_lower):
528
- formatted_analysis['classification'] = 'Beginner'
529
- else:
530
- formatted_analysis['classification'] = 'Intermediate'
531
-
532
- # Extract strengths and weaknesses
533
- strengths_section = ""
534
- weaknesses_section = ""
535
-
536
- # Look for strengths/weaknesses sections
537
- strengths_patterns = [
538
- r'(?:Strengths|Strong Points|Positives|Meets.*Standards)[\s\S]*?(?=(?:Weak|Priority|Improvement|Areas|$))',
539
- r'(?:Professional Level|Exceeds.*Standards)[\s\S]*?(?=(?:Below|Weak|Priority|$))'
540
- ]
541
-
542
- weaknesses_patterns = [
543
- r'(?:Weaknesses|Weak|Areas.*Improvement|Priority.*Areas|Below.*Standards)[\s\S]*?(?=(?:Recommendation|Priority|$))',
544
- r'(?:Critical|Important|Significant.*gaps?)[\s\S]*?(?=(?:Recommendation|$))'
545
- ]
546
-
547
- for pattern in strengths_patterns:
548
- match = re.search(pattern, raw_analysis, re.IGNORECASE)
549
- if match:
550
- strengths_section = match.group(0)
551
- break
552
-
553
- for pattern in weaknesses_patterns:
554
- match = re.search(pattern, raw_analysis, re.IGNORECASE)
555
- if match:
556
- weaknesses_section = match.group(0)
557
- break
558
-
559
- # Parse strengths from the section
560
- if strengths_section:
561
- strength_items = re.findall(r'[-•]\s*([^-•\n]+)', strengths_section)
562
- formatted_analysis['strengths'] = [item.strip() for item in strength_items[:4]] # Limit to 4
563
-
564
- # If no bullet points found, try to extract from general content
565
  if not formatted_analysis['strengths']:
566
- # Look for positive indicators in the full text
567
- positive_indicators = [
568
- r'(?:meets|exceeds|matches).*professional.*(?:standard|benchmark)',
569
- r'(?:excellent|good|strong).*(?:posture|rotation|extension|timing)',
570
- r'(?:consistent|solid).*(?:mechanics|form|technique)',
571
- r'(?:efficient|effective).*(?:transfer|generation|sequence)'
572
  ]
573
 
574
- for pattern in positive_indicators:
575
- matches = re.findall(pattern, raw_analysis, re.IGNORECASE)
576
- for match in matches[:2]: # Limit to avoid overwhelming
577
- formatted_analysis['strengths'].append(match.strip())
578
-
579
- # Parse weaknesses from the section
580
- if weaknesses_section:
581
- weakness_items = re.findall(r'[-•]\s*([^-•\n]+)', weaknesses_section)
582
- formatted_analysis['weaknesses'] = [item.strip() for item in weakness_items[:4]] # Limit to 4
583
 
584
- # If no bullet points found, try to extract from general content
585
  if not formatted_analysis['weaknesses']:
586
- # Look for negative indicators in the full text
587
- negative_indicators = [
588
- r'(?:below|under).*professional.*(?:standard|benchmark)',
589
- r'(?:poor|weak|limited).*(?:posture|rotation|extension|timing)',
590
- r'(?:inconsistent|unstable).*(?:mechanics|form|technique)',
591
- r'(?:inefficient|ineffective).*(?:transfer|generation|sequence)'
592
  ]
593
 
594
- for pattern in negative_indicators:
595
- matches = re.findall(pattern, raw_analysis, re.IGNORECASE)
596
- for match in matches[:2]: # Limit to avoid overwhelming
597
- formatted_analysis['weaknesses'].append(match.strip())
598
-
599
- # Extract priority improvements
600
- priority_patterns = [
601
- r'(?:Priority.*Improvement|Critical.*Areas?)[\s\S]*?(?=(?:Recommendation|$))',
602
- r'(?:1\..*?2\..*?3\.)', # Numbered list
603
- r'(?:Critical|Important|Fine-tuning)[\s\S]*?(?=(?:Critical|Important|Fine-tuning|$))'
604
- ]
605
-
606
- for pattern in priority_patterns:
607
- match = re.search(pattern, raw_analysis, re.IGNORECASE | re.DOTALL)
608
- if match:
609
- priority_text = match.group(0)
610
- # Extract numbered items
611
- numbered_items = re.findall(r'(\d+)\.\s*([^1-9\n]+)', priority_text)
612
- for num, item in numbered_items[:3]: # Limit to 3
613
- formatted_analysis['priority_improvements'].append({
614
- 'rank': int(num),
615
- 'description': item.strip()
616
- })
617
- break
618
-
619
- # If no numbered priorities found, create generic ones based on classification
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
620
  if not formatted_analysis['priority_improvements']:
621
  if formatted_analysis['classification'] == 'Beginner':
622
  formatted_analysis['priority_improvements'] = [
623
- {'rank': 1, 'description': 'Focus on fundamental posture and setup position'},
624
- {'rank': 2, 'description': 'Develop consistent tempo and timing'},
625
- {'rank': 3, 'description': 'Improve weight shift and balance throughout swing'}
626
  ]
627
  elif formatted_analysis['classification'] == 'Intermediate':
628
  formatted_analysis['priority_improvements'] = [
629
- {'rank': 1, 'description': 'Enhance kinematic sequence and body rotation'},
630
- {'rank': 2, 'description': 'Improve clubface control and swing path consistency'},
631
- {'rank': 3, 'description': 'Optimize energy transfer efficiency'}
632
  ]
633
  elif formatted_analysis['classification'] == 'Advanced':
634
  formatted_analysis['priority_improvements'] = [
635
- {'rank': 1, 'description': 'Fine-tune transition smoothness and timing'},
636
- {'rank': 2, 'description': 'Optimize power accumulation and release'},
637
- {'rank': 3, 'description': 'Enhance consistency under pressure'}
638
  ]
639
  else: # Professional
640
  formatted_analysis['priority_improvements'] = [
641
- {'rank': 1, 'description': 'Maintain current excellence with minor adjustments'},
642
- {'rank': 2, 'description': 'Focus on course management and strategy'},
643
- {'rank': 3, 'description': 'Continue physical conditioning for longevity'}
644
  ]
645
 
646
- # Ensure we have some default content if parsing failed
647
- if not formatted_analysis['strengths']:
648
- formatted_analysis['strengths'] = ['Swing analysis completed successfully']
649
-
650
- if not formatted_analysis['weaknesses']:
651
- formatted_analysis['weaknesses'] = ['Areas for improvement identified']
652
-
653
  return formatted_analysis
654
 
655
 
@@ -765,48 +772,75 @@ def display_formatted_analysis(analysis_data):
765
  rank = priority['rank']
766
  description = priority['description']
767
 
768
- # Extract improvement area and description if possible
769
- if ':' in description:
770
- area, desc = description.split(':', 1)
771
- area = area.strip()
772
- desc = desc.strip()
773
- elif '-' in description:
774
- parts = description.split('-', 1)
775
- if len(parts) == 2:
776
- area = parts[0].strip()
777
- desc = parts[1].strip()
778
- else:
779
- area = description
780
- desc = ""
 
 
 
 
 
 
 
 
 
 
781
  else:
782
- # Try to extract first sentence as area, rest as description
783
- sentences = description.split('. ')
784
- if len(sentences) > 1:
785
- area = sentences[0]
786
- desc = '. '.join(sentences[1:])
 
787
  else:
788
  area = description
789
  desc = ""
790
 
791
- # Color code by priority with better styling
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
792
  if rank == 1:
793
- st.markdown(f"""
794
- <div style='background-color: #ffebee; padding: 15px; border-left: 5px solid #f44336; border-radius: 5px; margin: 10px 0; word-wrap: break-word; overflow-wrap: break-word;'>
795
- <strong style='color: #d32f2f; font-size: 16px; display: block; margin-bottom: 8px;'>{rank}. MOST CRITICAL: {area}</strong>
796
- {f"<div style='color: #666; font-size: 14px; line-height: 1.4; word-wrap: break-word;'>{desc}</div>" if desc else ""}
797
- </div>
798
- """, unsafe_allow_html=True)
799
  elif rank == 2:
800
- st.markdown(f"""
801
- <div style='background-color: #fff8e1; padding: 15px; border-left: 5px solid #ff9800; border-radius: 5px; margin: 10px 0; word-wrap: break-word; overflow-wrap: break-word;'>
802
- <strong style='color: #f57c00; font-size: 16px; display: block; margin-bottom: 8px;'>{rank}. IMPORTANT: {area}</strong>
803
- {f"<div style='color: #666; font-size: 14px; line-height: 1.4; word-wrap: break-word;'>{desc}</div>" if desc else ""}
804
- </div>
805
- """, unsafe_allow_html=True)
806
  else:
807
- st.markdown(f"""
808
- <div style='background-color: #e3f2fd; padding: 15px; border-left: 5px solid #2196f3; border-radius: 5px; margin: 10px 0; word-wrap: break-word; overflow-wrap: break-word;'>
809
- <strong style='color: #1976d2; font-size: 16px; display: block; margin-bottom: 8px;'>{rank}. FOCUS AREA: {area}</strong>
810
- {f"<div style='color: #666; font-size: 14px; line-height: 1.4; word-wrap: break-word;'>{desc}</div>" if desc else ""}
811
- </div>
812
- """, unsafe_allow_html=True)
 
457
 
458
  ## ANALYSIS INSTRUCTIONS
459
 
460
+ Using the professional benchmarks above as your calibration reference, provide your analysis in the following EXACT structured format:
461
+
462
+ **PERFORMANCE_CLASSIFICATION:** [Professional/Advanced/Intermediate/Beginner]
463
+
464
+ **STRENGTHS:**
465
+ [Specific strength with metric comparison to professional standard]
466
+ [Another strength with professional benchmark reference]
467
+ [Third strength if applicable]
468
+
469
+ **WEAKNESSES:**
470
+ [Specific weakness with gap from professional standard]
471
+ [Another weakness with professional benchmark comparison]
472
+ • [Third weakness if applicable]
473
+
474
+ **PRIORITY_IMPROVEMENTS:**
475
+ 1. [Most Critical] Topic Name - Detailed description of current issue and what should be improved to reach professional standard
476
+ 2. [Important] Topic Name - Detailed description of current issue and desired improvement outcome
477
+ 3. [Focus Area] Topic Name - Detailed description of current issue and target improvement goal
478
+
479
+ IMPORTANT FORMATTING RULES:
480
+ - Use the exact headers shown above (PERFORMANCE_CLASSIFICATION, STRENGTHS, WEAKNESSES, PRIORITY_IMPROVEMENTS)
481
+ - For strengths and weaknesses, use bullet points (•)
482
+ - For priority improvements, use numbered format (1., 2., 3.) with priority level in brackets
483
+ - Each priority improvement must have: [Priority Level] Topic Name - Full description
484
+ - Provide complete sentences and descriptions - no incomplete thoughts
485
+ - Compare all metrics to the professional benchmarks provided above
486
+ - Be specific about what needs improvement and what the target should be
487
+
488
+ Remember: Professional golfers consistently achieve the benchmark metrics shown above. Use these as the gold standard for what constitutes excellent golf swing mechanics.
489
  """
490
 
491
  return prompt
 
509
  'priority_improvements': []
510
  }
511
 
512
+ # Extract classification using the new structured format
513
+ classification_match = re.search(r'\*\*PERFORMANCE_CLASSIFICATION:\*\*\s*([A-Za-z]+)', raw_analysis, re.IGNORECASE)
514
+ if classification_match:
515
+ formatted_analysis['classification'] = classification_match.group(1).title()
516
+ else:
517
+ # Fallback to original patterns
518
+ classification_patterns = [
519
+ r'(?:Performance Classification|Classification|Level).*?:\s*(Professional|Advanced|Intermediate|Beginner)',
520
+ r'(Professional|Advanced|Intermediate|Beginner)\s+(?:Level|Amateur)',
521
+ r'classified as\s+(Professional|Advanced|Intermediate|Beginner)',
522
+ r'(?:at|as)\s+(?:an?\s+)?(Professional|Advanced|Intermediate|Beginner)\s+level'
523
+ ]
524
+
525
+ for pattern in classification_patterns:
526
+ match = re.search(pattern, raw_analysis, re.IGNORECASE)
527
+ if match:
528
+ formatted_analysis['classification'] = match.group(1).title()
529
+ break
530
+
531
+ # Extract strengths using the new structured format
532
+ strengths_match = re.search(r'\*\*STRENGTHS:\*\*\s*(.*?)(?=\*\*WEAKNESSES:\*\*|\*\*PRIORITY_IMPROVEMENTS:\*\*|$)', raw_analysis, re.IGNORECASE | re.DOTALL)
533
+ if strengths_match:
534
+ strengths_text = strengths_match.group(1)
535
+ # Extract bullet points
536
+ strength_items = re.findall(r'•\s*([^\n•]+)', strengths_text)
537
+ formatted_analysis['strengths'] = [item.strip() for item in strength_items if item.strip()]
538
+
539
+ # Extract weaknesses using the new structured format
540
+ weaknesses_match = re.search(r'\*\*WEAKNESSES:\*\*\s*(.*?)(?=\*\*PRIORITY_IMPROVEMENTS:\*\*|$)', raw_analysis, re.IGNORECASE | re.DOTALL)
541
+ if weaknesses_match:
542
+ weaknesses_text = weaknesses_match.group(1)
543
+ # Extract bullet points
544
+ weakness_items = re.findall(r'•\s*([^\n•]+)', weaknesses_text)
545
+ formatted_analysis['weaknesses'] = [item.strip() for item in weakness_items if item.strip()]
546
+
547
+ # Extract priority improvements using the new structured format
548
+ priority_match = re.search(r'\*\*PRIORITY_IMPROVEMENTS:\*\*\s*(.*?)$', raw_analysis, re.IGNORECASE | re.DOTALL)
549
+ if priority_match:
550
+ priority_text = priority_match.group(1)
551
+ # Extract numbered items with priority levels and descriptions
552
+ priority_items = re.findall(r'(\d+)\.\s*\[(.*?)\]\s*(.*?)(?=\d+\.\s*\[|\Z)', priority_text, re.DOTALL)
553
+ for num, priority_level, description in priority_items[:3]: # Limit to 3
554
+ # Clean up the description
555
+ description = description.strip()
556
+ # Remove any trailing incomplete sentences
557
+ if description.endswith('...') or len(description.split('.')[-1].strip()) < 5:
558
+ sentences = description.split('.')
559
+ if len(sentences) > 1:
560
+ description = '.'.join(sentences[:-1]) + '.'
561
+
562
+ formatted_analysis['priority_improvements'].append({
563
+ 'rank': int(num),
564
+ 'priority_level': priority_level.strip(),
565
+ 'description': f"[{priority_level.strip()}] {description}"
566
+ })
567
+
568
+ # Fallback parsing if structured format wasn't used
 
 
 
 
569
  if not formatted_analysis['strengths']:
570
+ # Try original parsing methods for strengths
571
+ strengths_patterns = [
572
+ r'(?:Strengths|Strong Points|Positives|Meets.*Standards)[\s\S]*?(?=(?:Weak|Priority|Improvement|Areas|$))',
573
+ r'(?:Professional Level|Exceeds.*Standards)[\s\S]*?(?=(?:Below|Weak|Priority|$))'
 
 
574
  ]
575
 
576
+ for pattern in strengths_patterns:
577
+ match = re.search(pattern, raw_analysis, re.IGNORECASE)
578
+ if match:
579
+ strengths_section = match.group(0)
580
+ strength_items = re.findall(r'[-•]\s*([^-•\n]+)', strengths_section)
581
+ formatted_analysis['strengths'] = [item.strip() for item in strength_items[:4]]
582
+ break
 
 
583
 
 
584
  if not formatted_analysis['weaknesses']:
585
+ # Try original parsing methods for weaknesses
586
+ weaknesses_patterns = [
587
+ r'(?:Weaknesses|Weak|Areas.*Improvement|Priority.*Areas|Below.*Standards)[\s\S]*?(?=(?:Recommendation|Priority|$))',
588
+ r'(?:Critical|Important|Significant.*gaps?)[\s\S]*?(?=(?:Recommendation|$))'
 
 
589
  ]
590
 
591
+ for pattern in weaknesses_patterns:
592
+ match = re.search(pattern, raw_analysis, re.IGNORECASE)
593
+ if match:
594
+ weaknesses_section = match.group(0)
595
+ weakness_items = re.findall(r'[-•]\s*([^-•\n]+)', weaknesses_section)
596
+ formatted_analysis['weaknesses'] = [item.strip() for item in weakness_items[:4]]
597
+ break
598
+
599
+ if not formatted_analysis['priority_improvements']:
600
+ # Try original parsing methods for priorities
601
+ priority_patterns = [
602
+ r'(?:Priority.*Improvement|Critical.*Areas?)[\s\S]*?(?=(?:Recommendation|$))',
603
+ r'(?:1\..*?2\..*?3\.)', # Numbered list
604
+ r'(?:Critical|Important|Fine-tuning)[\s\S]*?(?=(?:Critical|Important|Fine-tuning|$))'
605
+ ]
606
+
607
+ for pattern in priority_patterns:
608
+ match = re.search(pattern, raw_analysis, re.IGNORECASE | re.DOTALL)
609
+ if match:
610
+ priority_text = match.group(0)
611
+ # Extract numbered items with better parsing
612
+ numbered_items = re.findall(r'(\d+)\.\s*([^1-9]+?)(?=\d+\.|$)', priority_text, re.DOTALL)
613
+ for num, item in numbered_items[:3]: # Limit to 3
614
+ # Clean up the item text
615
+ item = item.strip()
616
+ # Remove any trailing incomplete sentences
617
+ sentences = item.split('.')
618
+ if len(sentences) > 1 and len(sentences[-1].strip()) < 10:
619
+ item = '.'.join(sentences[:-1]) + '.'
620
+
621
+ formatted_analysis['priority_improvements'].append({
622
+ 'rank': int(num),
623
+ 'description': item
624
+ })
625
+ break
626
+
627
+ # If still no content found, use defaults based on classification
628
+ if not formatted_analysis['strengths']:
629
+ formatted_analysis['strengths'] = ['Swing analysis completed successfully']
630
+
631
+ if not formatted_analysis['weaknesses']:
632
+ formatted_analysis['weaknesses'] = ['Areas for improvement identified']
633
+
634
  if not formatted_analysis['priority_improvements']:
635
  if formatted_analysis['classification'] == 'Beginner':
636
  formatted_analysis['priority_improvements'] = [
637
+ {'rank': 1, 'description': '[Most Critical] Fundamental Posture and Setup - Focus on establishing proper spine angle and athletic stance throughout the swing for better consistency and power transfer.'},
638
+ {'rank': 2, 'description': '[Important] Tempo and Timing Development - Develop consistent swing rhythm and timing to improve sequence and control.'},
639
+ {'rank': 3, 'description': '[Focus Area] Weight Shift and Balance - Improve weight transfer from back foot to front foot during swing for better power and stability.'}
640
  ]
641
  elif formatted_analysis['classification'] == 'Intermediate':
642
  formatted_analysis['priority_improvements'] = [
643
+ {'rank': 1, 'description': '[Most Critical] Kinematic Sequence Enhancement - Improve body rotation coordination to generate more power and consistency.'},
644
+ {'rank': 2, 'description': '[Important] Clubface Control - Enhance swing path consistency for better ball striking accuracy.'},
645
+ {'rank': 3, 'description': '[Focus Area] Energy Transfer Efficiency - Optimize power transfer throughout the swing to maximize distance.'}
646
  ]
647
  elif formatted_analysis['classification'] == 'Advanced':
648
  formatted_analysis['priority_improvements'] = [
649
+ {'rank': 1, 'description': '[Most Critical] Transition Smoothness - Fine-tune timing and tempo to achieve professional-level consistency.'},
650
+ {'rank': 2, 'description': '[Important] Power Accumulation - Optimize energy storage and release for maximum clubhead speed.'},
651
+ {'rank': 3, 'description': '[Focus Area] Pressure Performance - Enhance consistency under competitive conditions.'}
652
  ]
653
  else: # Professional
654
  formatted_analysis['priority_improvements'] = [
655
+ {'rank': 1, 'description': '[Most Critical] Technical Refinement - Maintain excellence with minor adjustments to specific mechanics.'},
656
+ {'rank': 2, 'description': '[Important] Strategic Optimization - Focus on course management and scoring opportunities.'},
657
+ {'rank': 3, 'description': '[Focus Area] Physical Conditioning - Continue fitness work for career longevity and peak performance.'}
658
  ]
659
 
 
 
 
 
 
 
 
660
  return formatted_analysis
661
 
662
 
 
772
  rank = priority['rank']
773
  description = priority['description']
774
 
775
+ # Better extraction of improvement area and description
776
+ area = ""
777
+ desc = description
778
+
779
+ # Try different patterns to extract the main topic
780
+ if '[Most Critical]' in description or '[Important]' in description or '[Focus Area]' in description:
781
+ # Pattern: [Priority Level] Topic - Description
782
+ pattern = r'\[(.*?)\]\s*(.*?)(?:\s*-\s*(.*))?$'
783
+ match = re.search(pattern, description)
784
+ if match:
785
+ priority_level = match.group(1)
786
+ area = match.group(2).strip()
787
+ desc = match.group(3).strip() if match.group(3) else ""
788
+ elif ':' in description:
789
+ # Pattern: Topic: Description
790
+ parts = description.split(':', 1)
791
+ area = parts[0].strip()
792
+ desc = parts[1].strip()
793
+ elif ' - ' in description:
794
+ # Pattern: Topic - Description
795
+ parts = description.split(' - ', 1)
796
+ area = parts[0].strip()
797
+ desc = parts[1].strip()
798
  else:
799
+ # Try to extract first meaningful phrase as area
800
+ words = description.split()
801
+ if len(words) > 5:
802
+ # Take first 3-5 words as the area
803
+ area = ' '.join(words[:4])
804
+ desc = ' '.join(words[4:])
805
  else:
806
  area = description
807
  desc = ""
808
 
809
+ # Clean up area and description
810
+ area = area.replace('[Most Critical]', '').replace('[Important]', '').replace('[Focus Area]', '').strip()
811
+
812
+ # Ensure we have meaningful content
813
+ if not area or len(area) < 5:
814
+ area = f"Priority {rank} Improvement"
815
+
816
+ if not desc or len(desc) < 10:
817
+ # Provide a more complete description based on the area
818
+ if 'posture' in area.lower():
819
+ desc = "Work on maintaining proper spine angle and athletic stance throughout the swing for better consistency and power transfer."
820
+ elif 'tempo' in area.lower() or 'timing' in area.lower():
821
+ desc = "Focus on developing a smooth, consistent rhythm that allows for proper sequencing of body movements."
822
+ elif 'rotation' in area.lower():
823
+ desc = "Improve the coordination and range of motion in your body turn to generate more power and accuracy."
824
+ elif 'weight' in area.lower() or 'shift' in area.lower():
825
+ desc = "Practice transferring weight from back foot to front foot during the swing for better balance and power."
826
+ elif 'knee' in area.lower():
827
+ desc = "Work on maintaining proper knee flex and stability throughout the swing for better foundation and consistency."
828
+ elif 'hip' in area.lower():
829
+ desc = "Focus on improving hip mobility and thrust timing to enhance power generation and sequencing."
830
+ elif 'chest' in area.lower():
831
+ desc = "Improve chest rotation efficiency to better coordinate upper body movement with the swing sequence."
832
+ else:
833
+ desc = description # Use the full description if we can't categorize it
834
+
835
+ # Display using Streamlit's native components
836
  if rank == 1:
837
+ st.error(f"**{rank}. MOST CRITICAL: {area}**")
838
+ st.write(desc)
 
 
 
 
839
  elif rank == 2:
840
+ st.warning(f"**{rank}. IMPORTANT: {area}**")
841
+ st.write(desc)
 
 
 
 
842
  else:
843
+ st.info(f"**{rank}. FOCUS AREA: {area}**")
844
+ st.write(desc)
845
+
846
+ st.write("") # Add spacing between items