Spaces:
Sleeping
Sleeping
| """ | |
| Homeopathic Analyzer - Simple Working Version | |
| """ | |
| import gradio as gr | |
| import re | |
| from difflib import get_close_matches | |
| # ==================== SIMPLE DATABASE ==================== | |
| REMEDIES = { | |
| "Arnica Montana": { | |
| "description": "For trauma, injuries, bruising", | |
| "indications": ["injury", "bruise", "trauma", "sore", "shock"], | |
| "potency": "30C", | |
| "dosage": "Every 2-4 hours" | |
| }, | |
| "Belladonna": { | |
| "description": "Sudden fever, throbbing headache", | |
| "indications": ["fever", "headache", "inflammation", "red", "hot"], | |
| "potency": "30C", | |
| "dosage": "Every 1-2 hours" | |
| }, | |
| "Nux Vomica": { | |
| "description": "Digestive issues, irritability", | |
| "indications": ["digestive", "nausea", "irritable", "constipation", "hangover"], | |
| "potency": "6C", | |
| "dosage": "3 times daily" | |
| }, | |
| "Pulsatilla": { | |
| "description": "Changeable symptoms, weepy", | |
| "indications": ["changeable", "weepy", "colds", "digestive", "emotional"], | |
| "potency": "30C", | |
| "dosage": "Every 4 hours" | |
| }, | |
| "Bryonia Alba": { | |
| "description": "Worse from motion, thirsty", | |
| "indications": ["thirsty", "motion", "dry", "constipation", "joint pain"], | |
| "potency": "30C", | |
| "dosage": "Every 4 hours" | |
| } | |
| } | |
| # Common misspellings | |
| MISSPELLINGS = { | |
| "arnika": "Arnica Montana", | |
| "arnicum": "Arnica Montana", | |
| "belladona": "Belladonna", | |
| "nux vom": "Nux Vomica", | |
| "nuxvomica": "Nux Vomica", | |
| "pulsatila": "Pulsatilla", | |
| "bryonia": "Bryonia Alba", | |
| "argentum nitric": "Argentum Nitricum", | |
| "argentic nitric": "Argentum Nitricum" | |
| } | |
| # ==================== SIMPLE SEARCH ==================== | |
| def search_medicine_simple(query): | |
| """Simple search that actually works""" | |
| if not query or len(query) < 2: | |
| return [] | |
| query = query.lower().strip() | |
| results = [] | |
| # Check exact matches | |
| for name, data in REMEDIES.items(): | |
| if query in name.lower(): | |
| results.append({ | |
| "name": name, | |
| "match": "exact", | |
| "confidence": 100, | |
| "data": data | |
| }) | |
| # Check misspellings | |
| if query in MISSPELLINGS: | |
| correct_name = MISSPELLINGS[query] | |
| results.append({ | |
| "name": correct_name, | |
| "match": "corrected", | |
| "confidence": 90, | |
| "data": REMEDIES.get(correct_name, {}) | |
| }) | |
| # Check partial matches | |
| for name, data in REMEDIES.items(): | |
| name_lower = name.lower() | |
| if query in name_lower and not any(r["name"] == name for r in results): | |
| results.append({ | |
| "name": name, | |
| "match": "partial", | |
| "confidence": 80, | |
| "data": data | |
| }) | |
| # Check indications | |
| for name, data in REMEDIES.items(): | |
| for indication in data["indications"]: | |
| if query in indication.lower() and not any(r["name"] == name for r in results): | |
| results.append({ | |
| "name": name, | |
| "match": "indication", | |
| "confidence": 70, | |
| "data": data | |
| }) | |
| # Remove duplicates | |
| unique_results = [] | |
| seen = set() | |
| for r in results: | |
| if r["name"] not in seen: | |
| seen.add(r["name"]) | |
| unique_results.append(r) | |
| # Sort by confidence | |
| unique_results.sort(key=lambda x: x["confidence"], reverse=True) | |
| return unique_results[:5] | |
| # ==================== SIMPLE ANALYSIS ==================== | |
| def analyze_symptoms_simple(complaint, aggravations="", ameliorations="", emotional=""): | |
| """Simple analysis that actually works""" | |
| if not complaint: | |
| return [] | |
| complaint_lower = complaint.lower() | |
| aggravations_lower = aggravations.lower() | |
| ameliorations_lower = ameliorations.lower() | |
| emotional_lower = emotional.lower() | |
| matches = [] | |
| for remedy_name, remedy_data in REMEDIES.items(): | |
| score = 0 | |
| # Check complaint against indications | |
| for indication in remedy_data["indications"]: | |
| if indication in complaint_lower: | |
| score += 30 | |
| elif any(word in complaint_lower for word in indication.split()): | |
| score += 15 | |
| # Simple modality checking | |
| if "motion" in aggravations_lower and "bryonia" in remedy_name.lower(): | |
| score += 20 | |
| if "cold" in aggravations_lower and "arnica" in remedy_name.lower(): | |
| score += 20 | |
| if "heat" in aggravations_lower and "belladonna" in remedy_name.lower(): | |
| score += 20 | |
| if score > 10: | |
| matches.append({ | |
| "name": remedy_name, | |
| "score": min(100, score), | |
| "data": remedy_data, | |
| "reasons": get_match_reasons(complaint_lower, remedy_data) | |
| }) | |
| # Sort and return | |
| matches.sort(key=lambda x: x["score"], reverse=True) | |
| return matches[:3] | |
| def get_match_reasons(complaint, remedy_data): | |
| """Get simple match reasons""" | |
| reasons = [] | |
| for indication in remedy_data["indications"][:2]: | |
| if indication in complaint: | |
| reasons.append(f"Matches: {indication}") | |
| return reasons[:2] | |
| # ==================== GRADIO UI ==================== | |
| def create_search_results_html(results, query): | |
| """Create HTML for search results""" | |
| if not results: | |
| return f""" | |
| <div style='text-align: center; padding: 40px;'> | |
| <h3>No results found for "{query}"</h3> | |
| <p>Try: Arnica, Belladonna, Nux Vomica, Pulsatilla</p> | |
| </div> | |
| """ | |
| html = f"<h3>Found {len(results)} results for '{query}':</h3>" | |
| for i, result in enumerate(results, 1): | |
| html += f""" | |
| <div style='border: 1px solid #ddd; padding: 15px; margin: 10px 0; border-radius: 8px;'> | |
| <h4 style='margin: 0; color: #1e40af;'>{i}. {result['name']}</h4> | |
| <p style='margin: 5px 0; color: #666;'>{result['data']['description']}</p> | |
| <div style='display: flex; gap: 10px; margin: 10px 0;'> | |
| """ | |
| for indication in result['data']['indications'][:3]: | |
| html += f"<span style='background: #e5e7eb; padding: 4px 8px; border-radius: 4px; font-size: 12px;'>{indication}</span>" | |
| html += f""" | |
| </div> | |
| <div style='color: #4b5563; font-size: 14px;'> | |
| <strong>Potency:</strong> {result['data']['potency']} • | |
| <strong>Dosage:</strong> {result['data']['dosage']} | |
| </div> | |
| </div> | |
| """ | |
| return html | |
| def create_analysis_html(matches): | |
| """Create HTML for analysis results""" | |
| if not matches: | |
| return """ | |
| <div style='text-align: center; padding: 40px;'> | |
| <h3>No remedies match your symptoms</h3> | |
| <p>Try describing your symptoms in more detail.</p> | |
| </div> | |
| """ | |
| top_match = matches[0] | |
| html = f""" | |
| <div style='background: #f0f9ff; padding: 20px; border-radius: 10px; margin-bottom: 20px;'> | |
| <h3 style='margin: 0 0 15px 0; color: #0369a1;'>Top Recommendation</h3> | |
| <div style='background: white; padding: 15px; border-radius: 8px;'> | |
| <h4 style='margin: 0 0 10px 0; color: #1e40af;'>{top_match['name']} ({top_match['score']}% match)</h4> | |
| <p style='margin: 0 0 10px 0; color: #4b5563;'>{top_match['data']['description']}</p> | |
| <div style='display: flex; gap: 15px;'> | |
| <div style='flex: 1;'> | |
| <strong>Potency:</strong> {top_match['data']['potency']} | |
| </div> | |
| <div style='flex: 1;'> | |
| <strong>Dosage:</strong> {top_match['data']['dosage']} | |
| </div> | |
| </div> | |
| """ | |
| if top_match.get('reasons'): | |
| html += "<div style='margin-top: 15px;'><strong>Why this remedy:</strong><ul style='margin: 10px 0;'>" | |
| for reason in top_match['reasons']: | |
| html += f"<li>{reason}</li>" | |
| html += "</ul></div>" | |
| html += """ | |
| </div> | |
| </div> | |
| """ | |
| if len(matches) > 1: | |
| html += "<h4>Other possibilities:</h4>" | |
| for match in matches[1:]: | |
| html += f""" | |
| <div style='border: 1px solid #e5e7eb; padding: 12px; margin: 8px 0; border-radius: 6px;'> | |
| <strong>{match['name']}</strong> ({match['score']}%) - {match['data']['description']} | |
| </div> | |
| """ | |
| return html | |
| # ==================== GRADIO APP ==================== | |
| with gr.Blocks(title="Homeopathic Analyzer", theme=gr.themes.Soft()) as app: | |
| gr.Markdown("# 🏥 Homeopathic Analyzer") | |
| gr.Markdown("Simple and effective homeopathic analysis") | |
| with gr.Tabs(): | |
| with gr.TabItem("💊 Medicine Search"): | |
| gr.Markdown("### Search for homeopathic medicines") | |
| search_input = gr.Textbox( | |
| label="Medicine name", | |
| placeholder="e.g., Arnica, Belladonna, Nux Vomica...", | |
| scale=4 | |
| ) | |
| search_btn = gr.Button("Search", variant="primary") | |
| search_results = gr.HTML(label="Results") | |
| def search_handler(query): | |
| results = search_medicine_simple(query) | |
| return create_search_results_html(results, query) | |
| search_input.submit(search_handler, inputs=[search_input], outputs=[search_results]) | |
| search_btn.click(search_handler, inputs=[search_input], outputs=[search_results]) | |
| with gr.TabItem("🩺 Symptom Analysis"): | |
| gr.Markdown("### Enter your symptoms") | |
| complaint = gr.Textbox( | |
| label="Main complaint", | |
| placeholder="Describe your main symptoms...", | |
| lines=3 | |
| ) | |
| with gr.Row(): | |
| aggravations = gr.Textbox( | |
| label="What makes it worse?", | |
| placeholder="e.g., motion, cold, heat...", | |
| lines=2 | |
| ) | |
| ameliorations = gr.Textbox( | |
| label="What makes it better?", | |
| placeholder="e.g., rest, warmth, pressure...", | |
| lines=2 | |
| ) | |
| emotional = gr.Textbox( | |
| label="Emotional state (optional)", | |
| placeholder="e.g., anxious, irritable, weepy...", | |
| lines=2 | |
| ) | |
| analyze_btn = gr.Button("Analyze Symptoms", variant="primary") | |
| analysis_results = gr.HTML(label="Analysis Results") | |
| def analyze_handler(complaint_val, aggravations_val, ameliorations_val, emotional_val): | |
| matches = analyze_symptoms_simple( | |
| complaint_val, aggravations_val, ameliorations_val, emotional_val | |
| ) | |
| return create_analysis_html(matches) | |
| analyze_btn.click( | |
| analyze_handler, | |
| inputs=[complaint, aggravations, ameliorations, emotional], | |
| outputs=[analysis_results] | |
| ) | |
| # Footer | |
| gr.Markdown("---") | |
| gr.Markdown("*This tool is for educational purposes only. Consult a professional for medical advice.*") | |
| # Launch | |
| if __name__ == "__main__": | |
| app.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False | |
| ) |