Homoeopathy-Bot / app.py
yekkala's picture
Update app.py
c9a4c1f verified
"""
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
)