sunbal7 commited on
Commit
5190a0b
·
verified ·
1 Parent(s): 78f1ee5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +591 -492
app.py CHANGED
@@ -6,15 +6,10 @@ import pickle
6
  from PIL import Image
7
  import io
8
  import cv2
9
- import easyocr
10
  import os
11
  import plotly.graph_objects as go
12
  import plotly.express as px
13
  from datetime import datetime
14
- import requests
15
- import json
16
- import base64
17
- import tempfile
18
 
19
  # Set page config first
20
  st.set_page_config(
@@ -24,83 +19,146 @@ st.set_page_config(
24
  initial_sidebar_state="expanded"
25
  )
26
 
27
- # Custom CSS for styling
28
  def local_css():
29
  st.markdown("""
30
  <style>
31
  .main-header {
32
- font-size: 2.5rem;
33
- color: #2E86AB;
34
  text-align: center;
35
- margin-bottom: 2rem;
36
- font-weight: bold;
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
38
- .urdu-text {
39
- font-family: 'Arial', 'Noto Sans Arabic';
40
- font-size: 1.2rem;
41
- direction: rtl;
42
- text-align: right;
 
 
 
 
 
 
 
 
 
 
43
  }
44
  .risk-high {
45
- background-color: #ffcccc;
46
- padding: 15px;
47
- border-radius: 10px;
48
- border-left: 5px solid #dc3545;
 
 
49
  }
50
  .risk-medium {
51
- background-color: #fff3cd;
52
- padding: 15px;
53
- border-radius: 10px;
54
- border-left: 5px solid #ffc107;
 
 
55
  }
56
  .risk-low {
57
- background-color: #d4edda;
58
- padding: 15px;
59
- border-radius: 10px;
60
- border-left: 5px solid #28a745;
 
 
61
  }
62
  .priority-box {
63
- border: 2px solid #2E86AB;
64
- padding: 20px;
65
- border-radius: 10px;
66
- margin: 10px 0;
67
- background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
 
68
  }
69
  .stButton button {
70
  width: 100%;
71
- background: linear-gradient(45deg, #2E86AB, #A23B72);
72
  color: white;
73
  font-weight: bold;
74
  border: none;
75
- padding: 12px 24px;
76
- border-radius: 8px;
 
 
 
77
  }
78
- .dataframe table {
79
- width: 100%;
 
 
 
 
 
 
 
80
  }
81
  .dataframe th {
82
- background-color: #2E86AB;
83
  color: white;
84
  font-weight: bold;
 
 
 
 
 
85
  }
86
  .dataframe tr:nth-child(even) {
87
- background-color: #f2f2f2;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  }
89
  </style>
90
  """, unsafe_allow_html=True)
91
 
92
  # Initialize session state
93
  def init_session_state():
94
- if 'language' not in st.session_state:
95
- st.session_state.language = 'English'
96
  if 'patient_data' not in st.session_state:
97
  st.session_state.patient_data = {}
98
  if 'risk_scores' not in st.session_state:
99
  st.session_state.risk_scores = {}
100
- if 'chat_history' not in st.session_state:
101
- st.session_state.chat_history = []
102
- if 'groq_api_key' not in st.session_state:
103
- st.session_state.groq_api_key = ""
104
 
105
  # Load trained models
106
  @st.cache_resource(show_spinner=False)
@@ -157,228 +215,177 @@ def load_models():
157
  # Return rule-based fallback
158
  return "rule_based", "rule_based", "rule_based"
159
 
160
- # Groq API client using direct HTTP requests
161
- class GroqClient:
162
- def __init__(self, api_key):
163
- self.api_key = api_key
164
- self.base_url = "https://api.groq.com/openai/v1"
165
- self.headers = {
166
- "Authorization": f"Bearer {api_key}",
167
- "Content-Type": "application/json"
168
- }
169
-
170
- def chat_completions_create(self, messages, model="llama3-8b-8192", temperature=0.3, max_tokens=512):
171
- try:
172
- url = f"{self.base_url}/chat/completions"
173
- data = {
174
- "messages": messages,
175
- "model": model,
176
- "temperature": temperature,
177
- "max_tokens": max_tokens,
178
- "top_p": 0.9
179
- }
180
-
181
- response = requests.post(url, headers=self.headers, json=data, timeout=30)
182
- response.raise_for_status()
183
-
184
- result = response.json()
185
- return result
186
-
187
- except Exception as e:
188
- raise Exception(f"Groq API error: {str(e)}")
189
-
190
- # Urdu translations
191
- URDU_TRANSLATIONS = {
192
- "AI-Priority OPD System": "AI-ترجیحی OPD سسٹم",
193
- "Patient Information": "مریض کی معلومات",
194
- "Name": "نام",
195
- "Age": "عمر",
196
- "Gender": "جنس",
197
- "Contact": "رابطہ نمبر",
198
- "Medical History": "طبی تاریخ",
199
- "Vital Signs": "اہم علامات",
200
- "Blood Pressure (systolic)": "بلڈ پریشر (سسٹولک)",
201
- "Blood Pressure (diastolic)": "بلڈ پریشر (ڈائیسٹولک)",
202
- "Heart Rate": "دل کی دھڑکن",
203
- "Cholesterol Level": "کولیسٹرول کی سطح",
204
- "Blood Glucose": "خون میں گلوکوز",
205
- "BMI": "باڈی ماس انڈیکس",
206
- "Symptoms": "علامات",
207
- "Chest Pain": "سینے میں درد",
208
- "Shortness of Breath": "سانس لینے میں دشواری",
209
- "Fatigue": "تھکاوٹ",
210
- "Upload Prescription": "نسخہ اپ لوڈ کریں",
211
- "Calculate Risk Score": "خطرے کا اسکور معلوم کریں",
212
- "High Priority - Emergency Care Required": "اعلی ترجیح - ہنگامی علاج کی ضرورت",
213
- "Medium Priority - Same Day Consultation": "درمیانی ترجیح - اسی دن مشورہ",
214
- "Low Priority - Routine Appointment": "کم ترجیح - معمول کی ملاقات",
215
- "Healthcare Chatbot": "ہیلتھ کیئر چیٹ بوٹ",
216
- "Ask health-related questions": "صحت سے متعلق سوالات پوچھیں"
217
- }
218
-
219
- class OCRProcessor:
220
  def __init__(self):
221
- # Initialize EasyOCR reader with error handling
222
- try:
223
- self.reader = easyocr.Reader(['en']) # English only for medical text
224
- except Exception as e:
225
- st.error(f"OCR initialization failed: {str(e)}")
226
- self.reader = None
227
-
228
- def preprocess_image(self, image):
229
- """Enhanced image preprocessing for better OCR accuracy"""
230
- try:
231
- # Convert to numpy array
232
- img_array = np.array(image)
233
-
234
- # Convert to grayscale if colored
235
- if len(img_array.shape) == 3:
236
- gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
237
- else:
238
- gray = img_array
239
-
240
- # Apply different preprocessing techniques
241
- # 1. Gaussian blur to reduce noise
242
- blurred = cv2.GaussianBlur(gray, (3, 3), 0)
243
-
244
- # 2. Adaptive thresholding
245
- thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
246
- cv2.THRESH_BINARY, 11, 2)
247
-
248
- # 3. Morphological operations to clean up the image
249
- kernel = np.ones((2, 2), np.uint8)
250
- processed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
251
-
252
- return processed
253
-
254
- except Exception as e:
255
- st.error(f"Image processing error: {str(e)}")
256
- return np.array(image)
257
-
258
- def extract_text(self, image):
259
- """Extract text from prescription image using EasyOCR"""
260
- try:
261
- if self.reader is None:
262
- return "OCR not available. Please check EasyOCR installation."
263
-
264
- # Preprocess image
265
- processed_image = self.preprocess_image(image)
266
-
267
- # Perform OCR
268
- results = self.reader.readtext(processed_image, detail=0, paragraph=True)
269
-
270
- # Combine all detected text
271
- extracted_text = "\n".join(results)
272
-
273
- return extracted_text.strip() if extracted_text.strip() else "No text detected in the image."
274
-
275
- except Exception as e:
276
- return f"OCR Error: {str(e)}"
277
-
278
- def calculate_ocr_accuracy(self, extracted_text):
279
- """Estimate OCR accuracy based on text quality"""
280
- if not extracted_text or len(extracted_text.strip()) == 0 or "No text detected" in extracted_text:
281
- return 0
282
-
283
- # Basic heuristics for accuracy estimation
284
- text_length = len(extracted_text)
285
- word_count = len(extracted_text.split())
286
-
287
- # Check for common medical terms
288
- medical_terms = ['tablet', 'mg', 'ml', 'daily', 'twice', 'capsule', 'injection']
289
- found_terms = sum(1 for term in medical_terms if term in extracted_text.lower())
290
-
291
- # Calculate confidence score
292
- length_score = min(100, (text_length / 50) * 100) # More text = higher confidence
293
- word_score = min(100, (word_count / 10) * 100) # More words = higher confidence
294
- medical_score = (found_terms / len(medical_terms)) * 100
295
-
296
- # Weighted average
297
- accuracy = (length_score * 0.3 + word_score * 0.3 + medical_score * 0.4)
298
-
299
- return min(95, accuracy) # Cap at 95% for realistic estimates
300
-
301
- class HealthcareChatbot:
302
- def __init__(self, groq_client=None):
303
- self.client = groq_client
304
- self.system_prompt = """You are a helpful and professional healthcare assistant designed for Pakistani patients.
305
- Provide accurate, culturally appropriate medical advice in both English and Urdu.
306
- Focus on preventive care, symptom explanation, and when to seek medical attention.
307
- Always emphasize that you are an AI assistant and recommend consulting healthcare professionals for serious conditions."""
308
-
309
- # Fallback responses in case API is not available
310
- self.fallback_responses = {
311
- 'heart': {
312
- 'English': "**Heart Health Tips:**\n\n• Maintain a healthy diet low in saturated fats\n• Exercise regularly for 30 minutes daily\n• Monitor blood pressure regularly\n• Avoid smoking and limit alcohol\n• Manage stress through relaxation techniques\n\n⚠️ For chest pain or severe symptoms, seek immediate medical attention.",
313
- 'Urdu': "**دل کی صحت کے نکات:**\n\n• سیر شدہ چکنائی سے پاک صحت مند غذا کھائیں\n• روزانہ 30 منٹ باقاعدگی سے ورزش کریں\n• بلڈ پریشر کو باقاعدگی سے چیک کریں\n• تمباکو نوشی سے پرہیز کریں\n• آرام کی تکنیکوں کے ذریعے تناؤ کا انتظام کریں\n\n⚠️ سینے میں درد یا شدید علامات کی صورت میں فوری طبی امداد حاصل کریں۔"
314
  },
315
  'diabetes': {
316
- 'English': "**Diabetes Management Tips:**\n\n• Monitor blood sugar levels regularly\n• Follow a balanced diet with controlled carbs\n• Take medications as prescribed\n• Stay physically active\n• Get regular eye and foot checkups\n\n⚠️ Consult your doctor for personalized diabetes management.",
317
- 'Urdu': "**ذیابیطس کے انتظام کے نکات:**\n\n• خون میں شکر کی سطح کو باقاعدگی سے چیک کریں\n• کنٹرول کاربوہائیڈریٹ کے ساتھ متوازن غذا کھائیں\n• دوائیں ڈاکٹر کے مشورے کے مطابق لیں\n• جسمانی طور پر متحرک رہیں\n• آنکھوں اور پاؤں کی باقاعدہ جانچ کروائیں\n\n⚠️ ذاتی نوعیت کے ذیابیطس کے انتظام کے لیے اپنے ڈاکٹر سے مشورہ کریں۔"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  },
319
  'hypertension': {
320
- 'English': "**Blood Pressure Management:**\n\n• Reduce salt intake to less than 5g daily\n• Practice stress management techniques\n• Maintain healthy body weight\n• Limit caffeine and alcohol\n• Take prescribed medications consistently\n\n⚠️ Regularly monitor your blood pressure readings.",
321
- 'Urdu': "**بلڈ پریشر کے انتظام کے نکات:**\n\n• روزانہ نمک کی مقدار 5 گرام سے کم رکھیں\n• تناؤ کے انتظام کی تکنیکیں اپنائیں\n• صحت مند جسمانی وزن برقرار رکھیں\n• کیفین اور الکحل کو محدود کریں\n• تجویز کردہ دوائیں مسلسل لیں\n\n⚠️ اپنے بلڈ پریشر کی پیمائش کو باقاعدگی سے مانیٹر کریں۔"
322
- },
323
- 'general': {
324
- 'English': "**General Health Tips:**\n\nGet 7-9 hours of quality sleep each night\n• Stay hydrated by drinking 8-10 glasses of water daily\n• Practice good hygiene and regular hand washing\n• Get regular health check-ups and screenings\n• Maintain a positive outlook and social connections\n\n⚠️ For specific health concerns, consult a healthcare professional.",
325
- 'Urdu': "**عام صحت کے نکات:**\n\nہر رات 7-9 گھنٹے کی معیاری نیند لیں\n• روزانہ 8-10 گلاس پانی پی کر ہائیڈریٹ رہیں\n• اچھی حفظان صحت اور باقاعدہ ہاتھ دھونے کی مشق کریں\n• باقاعدہ صحت کی جانچ اور اسکریننگ کروائیں\n• مثبت نقطہ نظر اور سماجی رابطے برقرار رکھیں\n\n⚠️ مخصوص صحت کے مسائل کے لیے ہیلتھ کیئر پروفیشنل سے مشورہ کریں۔"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
  }
327
  }
328
 
329
- def get_response(self, query, language='English'):
330
- """Generate healthcare chatbot response using Groq API or fallback"""
331
- try:
332
- if self.client is None:
333
- return self._get_fallback_response(query, language)
334
-
335
- # Enhanced system prompt based on language
336
- enhanced_system_prompt = self.system_prompt
337
- if language == 'Urdu':
338
- enhanced_system_prompt += " Respond in Urdu with proper medical terminology and cultural sensitivity."
339
- else:
340
- enhanced_system_prompt += " Respond in English with clear, professional medical advice."
341
-
342
- # Create conversation context
343
- messages = [
344
- {"role": "system", "content": enhanced_system_prompt},
345
- {"role": "user", "content": query}
346
- ]
347
-
348
- # Generate response using Groq API
349
- response = self.client.chat_completions_create(
350
- messages=messages,
351
- model="llama3-8b-8192",
352
- temperature=0.3,
353
- max_tokens=512
354
- )
355
-
356
- bot_response = response['choices'][0]['message']['content']
357
-
358
- # Add disclaimer
359
- if language == 'Urdu':
360
- bot_response += "\n\n⚠️ براہ کرم نوٹ کریں: یہ ایک AI اسسٹنٹ ہے۔ سنگین طبی حالات کے لیے ہمیشہ کوالیفائیڈ ڈاکٹر سے مشورہ کریں۔"
361
- else:
362
- bot_response += "\n\n⚠️ Please note: This is an AI assistant. Always consult qualified doctors for serious medical conditions."
363
-
364
- return bot_response
365
-
366
- except Exception as e:
367
- st.error(f"Chatbot error: {str(e)}")
368
- return self._get_fallback_response(query, language)
369
-
370
- def _get_fallback_response(self, query, language):
371
- """Provide fallback responses when API is unavailable"""
372
- query_lower = query.lower()
373
-
374
- if any(word in query_lower for word in ['heart', 'cardiac', 'chest pain', 'cholesterol']):
375
- return self.fallback_responses['heart'][language]
376
- elif any(word in query_lower for word in ['diabetes', 'sugar', 'glucose', 'insulin']):
377
- return self.fallback_responses['diabetes'][language]
378
- elif any(word in query_lower for word in ['blood pressure', 'hypertension', 'bp']):
379
- return self.fallback_responses['hypertension'][language]
380
  else:
381
- return self.fallback_responses['general'][language]
 
 
 
382
 
383
  def calculate_priority_score(heart_risk, diabetes_risk, hypertension_risk):
384
  """Calculate integrated priority score with clinical weighting"""
@@ -504,6 +511,75 @@ def prepare_features_for_models(age, bp_systolic, bp_diastolic, heart_rate, chol
504
 
505
  return heart_features, diabetes_features, hypertension_features
506
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
507
  def main():
508
  # Load custom CSS
509
  local_css()
@@ -513,75 +589,116 @@ def main():
513
  with st.spinner("🔄 Loading AI models..."):
514
  heart_model, diabetes_model, hypertension_model = load_models()
515
 
516
- # Initialize processors
517
- ocr_processor = OCRProcessor()
518
 
519
- # Language selector in sidebar
520
  with st.sidebar:
521
- st.markdown("<h2 style='text-align: center; color: #2E86AB;'>🏥 AI-Priority OPD</h2>",
522
- unsafe_allow_html=True)
523
-
524
- # Groq API Configuration
525
- st.markdown("---")
526
- st.subheader("API Configuration")
527
- groq_api_key = st.text_input("Enter Groq API Key:", type="password",
528
- value=st.session_state.groq_api_key,
529
- help="Get your API key from https://console.groq.com")
530
-
531
- if groq_api_key:
532
- st.session_state.groq_api_key = groq_api_key
533
- groq_client = GroqClient(groq_api_key)
534
- chatbot = HealthcareChatbot(groq_client)
535
- st.success("✅ Groq API configured successfully!")
536
- else:
537
- st.warning("⚠️ Please enter Groq API key to enable advanced chatbot")
538
- chatbot = HealthcareChatbot(None)
539
 
 
540
  language = st.radio(
541
  "Select Language / زبان منتخب کریں",
542
  ["English", "Urdu"],
543
- key="language_selector"
 
544
  )
545
 
546
  st.markdown("---")
547
 
 
548
  if language == "English":
549
- st.subheader("Quick Actions")
550
- if st.button("🆕 New Patient Assessment", use_container_width=True):
551
- st.session_state.patient_data = {}
552
- st.session_state.risk_scores = {}
553
- st.session_state.chat_history = []
554
- st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  else:
556
- st.subheader("فوری اقدامات")
557
- if st.button("🆕 نیا مریض تشخیص", use_container_width=True):
558
- st.session_state.patient_data = {}
559
- st.session_state.risk_scores = {}
560
- st.session_state.chat_history = []
561
- st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
562
 
563
- # Main header
564
- if language == "English":
565
- st.markdown('<h1 class="main-header">🏥 AI-Priority OPD System</h1>', unsafe_allow_html=True)
566
- st.markdown("### Smart Patient Triage and Priority Management for Pakistani Healthcare")
567
- else:
568
- st.markdown('<h1 class="main-header">🏥 AI-ترجیحی OPD سسٹم</h1>', unsafe_allow_html=True)
569
- st.markdown("### پاکستانی ہیلتھ کیئر کے لیے ذہین مریض کی درجہ بندی اور ترجیحی انتظام")
 
 
 
 
570
 
571
  # Create tabs
572
  if language == "English":
573
- tab_names = ["Patient Assessment", "Prescription OCR", "Health Chatbot", "Analytics"]
574
  else:
575
- tab_names = ["مریض تشخیص", "نسخہ OCR", "ہیلتھ چیٹ بوٹ", "تجزیات"]
576
 
577
- tab1, tab2, tab3, tab4 = st.tabs(tab_names)
578
 
579
  with tab1:
580
  # Patient Assessment Form
 
 
581
  if language == "English":
582
- st.header("👨‍⚕️ Patient Assessment & Risk Scoring")
 
583
  else:
584
- st.header("👨‍⚕️ مریض تشخیص اور خطرے کا اسکورنگ")
 
585
 
586
  with st.form("patient_assessment_form"):
587
  col1, col2 = st.columns(2)
@@ -589,14 +706,14 @@ def main():
589
  with col1:
590
  # Basic Information
591
  if language == "English":
592
- st.subheader("Personal Information")
593
  name = st.text_input("Full Name", placeholder="Enter patient's full name")
594
  age = st.number_input("Age", min_value=1, max_value=120, value=45,
595
  help="Patient's age in years")
596
  gender = st.selectbox("Gender", ["Male", "Female", "Other"])
597
  contact = st.text_input("Contact Number", placeholder="03XX-XXXXXXX")
598
  else:
599
- st.subheader("ذاتی معلومات")
600
  name = st.text_input("مکمل نام", placeholder="مریض کا مکمل نام درج کریں")
601
  age = st.number_input("عمر", min_value=1, max_value=120, value=45,
602
  help="مریض کی عمر سالوں میں")
@@ -606,7 +723,7 @@ def main():
606
  with col2:
607
  # Vital Signs
608
  if language == "English":
609
- st.subheader("Clinical Parameters")
610
  bp_systolic = st.number_input("Blood Pressure (systolic)",
611
  min_value=70, max_value=250, value=120,
612
  help="Systolic blood pressure in mmHg")
@@ -622,7 +739,7 @@ def main():
622
  min_value=50, max_value=500, value=95)
623
  bmi = st.slider("BMI", min_value=15.0, max_value=40.0, value=23.5, step=0.1)
624
  else:
625
- st.subheader("کلینیکل پیرامیٹرز")
626
  bp_systolic = st.number_input("بلڈ پریشر (سسٹولک)",
627
  min_value=70, max_value=250, value=120,
628
  help="سسٹولک بلڈ پریشر mmHg میں")
@@ -640,7 +757,7 @@ def main():
640
 
641
  # Symptoms Section
642
  if language == "English":
643
- st.subheader("Reported Symptoms")
644
  col3, col4 = st.columns(2)
645
  with col3:
646
  chest_pain = st.checkbox("Chest Pain or Discomfort")
@@ -651,7 +768,7 @@ def main():
651
  dizziness = st.checkbox("Dizziness or Lightheadedness")
652
  blurred_vision = st.checkbox("Blurred Vision")
653
  else:
654
- st.subheader("رپورٹ کردہ علامات")
655
  col3, col4 = st.columns(2)
656
  with col3:
657
  chest_pain = st.checkbox("سینے میں درد یا بے چینی")
@@ -690,6 +807,21 @@ def main():
690
  'blurred_vision': 1 if blurred_vision else 0
691
  }
692
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
693
  # Get predictions based on available models
694
  if heart_model != "rule_based" and diabetes_model != "rule_based" and hypertension_model != "rule_based":
695
  # Use trained models
@@ -734,6 +866,13 @@ def main():
734
  'recommendation': recommendation,
735
  'level': priority_level
736
  }
 
 
 
 
 
 
 
737
 
738
  # Display results
739
  st.markdown("---")
@@ -741,9 +880,9 @@ def main():
741
 
742
  # Risk Scores Visualization
743
  if language == "English":
744
- st.subheader("📊 Disease Risk Assessment")
745
  else:
746
- st.subheader("📊 بیماری کے خطرے کا اندازہ")
747
 
748
  col5, col6, col7, col8 = st.columns(4)
749
 
@@ -810,228 +949,188 @@ def main():
810
 
811
  st.markdown('</div>', unsafe_allow_html=True)
812
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
813
  except Exception as e:
814
  st.error(f"❌ Error in risk assessment: {str(e)}")
 
 
815
 
816
  with tab2:
817
- # Prescription OCR
 
 
818
  if language == "English":
819
- st.header("📄 Prescription OCR Analysis")
820
- st.write("Upload a prescription image to extract medication information automatically")
821
  else:
822
- st.header("📄 نسخہ OCR تجزیہ")
823
- st.write("دوائی کی معلومات خود بخود نکالنے کے لیے نسخہ کی تصویر اپ لوڈ کریں")
824
-
825
- uploaded_file = st.file_uploader(
826
- "Choose prescription image..." if language == "English" else "نسخہ تصویر منتخب کریں...",
827
- type=['png', 'jpg', 'jpeg'],
828
- help="Upload a clear image of the medical prescription"
829
- )
830
 
831
- if uploaded_file is not None:
832
- # Display uploaded image
833
- image = Image.open(uploaded_file)
834
- st.image(image, caption="📷 Uploaded Prescription" if language == "English" else "📷 اپ لوڈ کردہ نسخہ",
835
- use_column_width=True)
836
-
837
- if st.button("🔍 Extract Text" if language == "English" else "🔍 متن نکالیں",
838
- use_container_width=True):
839
- with st.spinner("🔄 Processing prescription image..." if language == "English"
840
- else "🔄 نسخہ تصویر پروسیس ہو رہی ہے..."):
841
- extracted_text = ocr_processor.extract_text(image)
842
- accuracy = ocr_processor.calculate_ocr_accuracy(extracted_text)
843
-
844
- if extracted_text and "No text detected" not in extracted_text and "OCR Error" not in extracted_text:
845
- st.success(f"✅ Text extraction completed! (Estimated Accuracy: {accuracy:.1f}%)")
846
-
847
- if language == "English":
848
- st.subheader("Extracted Medication Information:")
849
- else:
850
- st.subheader("نکالی گئی دوائی کی معلومات:")
851
-
852
- # Display extracted text in expandable area
853
- with st.expander("View Extracted Text" if language == "English" else "نکالا گیا متن دیکھیں", expanded=True):
854
- st.text_area("", extracted_text, height=200, key="extracted_text")
855
-
856
- # Basic medication analysis
857
- if language == "English":
858
- st.subheader("📋 Medication Analysis")
859
- else:
860
- st.subheader("📋 دوائی کا تجزیہ")
861
-
862
- # Simple medication pattern detection
863
- medications_detected = 0
864
- if any(term in extracted_text.lower() for term in ['tablet', 'tab']):
865
- medications_detected += 1
866
- if any(term in extracted_text.lower() for term in ['mg', 'ml']):
867
- medications_detected += 1
868
- if any(term in extracted_text.lower() for term in ['daily', 'twice', 'thrice']):
869
- medications_detected += 1
870
-
871
- col_med1, col_med2 = st.columns(2)
872
- with col_med1:
873
- st.metric("Medications Detected", medications_detected)
874
- with col_med2:
875
- st.metric("OCR Confidence", f"{accuracy:.1f}%")
876
-
877
- else:
878
- st.error("�� No text could be extracted from the image. Please try with a clearer image.")
879
-
880
- if language == "English":
881
- st.info("💡 Tips for better OCR results:\n- Use good lighting\n- Ensure clear focus\n- Avoid shadows\n- Straight angle photo")
882
- else:
883
- st.info("💡 بہتر OCR نتائج کے لیے نکات:\n- اچھی روشنی استعمال کریں\n- واضح فوکس یقینی بنائیں\n- سایوں سے پرہیز کریں\n- سیدھے زاویے کی تصویر")
884
-
885
- with tab3:
886
- # Healthcare Chatbot
887
  if language == "English":
888
- st.header("💬 Healthcare Assistant Chatbot")
889
- st.write("Ask health-related questions and get personalized advice in English or Urdu")
 
 
890
  else:
891
- st.header("💬 ہیلتھ کیئر اسسٹنٹ چیٹ بوٹ")
892
- st.write("صحت سے متعلق سوالات پوچھیں اور انگریزی یا اردو میں ذاتی مشورہ حاصل کریں")
 
 
893
 
894
- # Display chat history
895
- for message in st.session_state.chat_history:
896
- with st.chat_message(message["role"]):
897
- if message["role"] == "user":
898
- st.markdown(message["content"])
899
- else:
900
- # Format bot response with better styling
901
- st.markdown(f"**🤖 Healthcare Assistant:**\n\n{message['content']}")
 
902
 
903
- # Chat input
904
- if prompt := st.chat_input(
905
- "Type your health question here..." if language == "English"
906
- else "اپنا صحت کا سوال یہاں ٹائپ کریں..."
907
- ):
908
- # Add user message to chat history
909
- st.session_state.chat_history.append({"role": "user", "content": prompt})
910
-
911
- # Generate bot response
912
- with st.chat_message("assistant"):
913
- with st.spinner("💭 Analyzing your question..." if language == "English" else "💭 آپ کا سوال تجزیہ ہو رہا ہے..."):
914
- response = chatbot.get_response(prompt, language)
915
- st.markdown(f"**🤖 Healthcare Assistant:**\n\n{response}")
916
-
917
- # Add assistant response to chat history
918
- st.session_state.chat_history.append({"role": "assistant", "content": response})
919
-
920
- # Limit chat history to last 10 messages
921
- if len(st.session_state.chat_history) > 10:
922
- st.session_state.chat_history = st.session_state.chat_history[-10:]
923
 
924
- # Quick action buttons
925
  if language == "English":
926
- st.subheader("Quick Health Topics")
 
927
  else:
928
- st.subheader("فوری صحت کے موضوعات")
 
929
 
930
- col_qa1, col_qa2, col_qa3 = st.columns(3)
 
931
 
932
- with col_qa1:
933
- if st.button("❤️ Heart Health", use_container_width=True):
934
- st.session_state.chat_history.append({
935
- "role": "user",
936
- "content": "Tell me about heart health and prevention tips"
937
- })
938
- st.rerun()
939
 
940
- with col_qa2:
941
- if st.button("🩺 Diabetes", use_container_width=True):
942
- st.session_state.chat_history.append({
943
- "role": "user",
944
- "content": "What are the symptoms and management of diabetes?"
945
- })
946
- st.rerun()
947
 
948
- with col_qa3:
949
- if st.button("💓 Blood Pressure", use_container_width=True):
950
- st.session_state.chat_history.append({
951
- "role": "user",
952
- "content": "How to control high blood pressure naturally?"
953
- })
954
- st.rerun()
955
-
956
- with tab4:
957
- # Analytics Dashboard
958
- if language == "English":
959
- st.header("📈 System Analytics & Performance")
960
- else:
961
- st.header("📈 سسٹم تجزیات اور کارکردگی")
962
 
963
- # Real-time performance metrics based on actual usage
964
- if 'risk_scores' in st.session_state and st.session_state.risk_scores:
965
- recent_priority = st.session_state.risk_scores.get('priority', 0)
966
- col9, col10, col11, col12 = st.columns(4)
967
-
968
- with col9:
969
- st.metric("Current Patient Priority", f"{recent_priority:.1%}")
970
- with col10:
971
- st.metric("Risk Assessment", "Completed")
972
- with col11:
973
- st.metric("Model Confidence", "High")
974
- with col12:
975
- st.metric("Processing Time", "< 2s")
976
- else:
977
  if language == "English":
978
- st.info("👆 Complete a patient assessment to see analytics")
979
  else:
980
- st.info("👆 تجزیات دیکھنے کے لیے مریض کی تشخیص مکمل کریں")
 
981
 
982
  # Analytics Charts
983
- if 'risk_scores' in st.session_state and st.session_state.risk_scores:
984
  col_chart1, col_chart2 = st.columns(2)
985
 
986
  with col_chart1:
987
  if language == "English":
988
- st.subheader("Current Patient Risk Distribution")
989
  else:
990
- st.subheader("موجودہ مریض کے خطرے کی تقسیم")
991
 
 
 
992
  risk_data = pd.DataFrame({
993
  'Condition': ['Heart Disease', 'Diabetes', 'Hypertension'],
994
  'Risk Score': [
995
- st.session_state.risk_scores['heart'],
996
- st.session_state.risk_scores['diabetes'],
997
- st.session_state.risk_scores['hypertension']
998
  ]
999
  })
1000
 
1001
  fig = px.bar(risk_data, x='Condition', y='Risk Score',
1002
- color='Risk Score', color_continuous_scale='RdYlGn_r')
 
1003
  st.plotly_chart(fig, use_container_width=True)
1004
 
1005
  with col_chart2:
1006
  if language == "English":
1007
- st.subheader("Priority Level")
1008
  else:
1009
- st.subheader("ترجیحی سطح")
1010
-
1011
- priority_level = st.session_state.risk_scores['level']
1012
- priority_colors = {
1013
- 'EMERGENCY_CARE': '#dc3545',
1014
- 'SAME_DAY_CONSULT': '#ffc107',
1015
- 'ROUTINE_APPOINTMENT': '#28a745'
1016
- }
1017
 
1018
- fig = go.Figure(go.Indicator(
1019
- mode = "gauge+number",
1020
- value = st.session_state.risk_scores['priority'] * 100,
1021
- domain = {'x': [0, 1], 'y': [0, 1]},
1022
- title = {'text': "Priority Score"},
1023
- gauge = {
1024
- 'axis': {'range': [0, 100]},
1025
- 'bar': {'color': priority_colors.get(priority_level, '#2E86AB')},
1026
- 'steps': [
1027
- {'range': [0, 55], 'color': "lightgray"},
1028
- {'range': [55, 75], 'color': "yellow"},
1029
- {'range': [75, 100], 'color': "red"}
1030
- ]
1031
- }
1032
- ))
1033
- fig.update_layout(height=300)
1034
- st.plotly_chart(fig, use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1035
 
1036
  if __name__ == "__main__":
1037
  main()
 
6
  from PIL import Image
7
  import io
8
  import cv2
 
9
  import os
10
  import plotly.graph_objects as go
11
  import plotly.express as px
12
  from datetime import datetime
 
 
 
 
13
 
14
  # Set page config first
15
  st.set_page_config(
 
19
  initial_sidebar_state="expanded"
20
  )
21
 
22
+ # Professional CSS Styling
23
  def local_css():
24
  st.markdown("""
25
  <style>
26
  .main-header {
27
+ font-size: 3rem;
28
+ color: #1f77b4;
29
  text-align: center;
30
+ margin-bottom: 1rem;
31
+ font-weight: 700;
32
+ background: linear-gradient(135deg, #1f77b4, #2e86ab);
33
+ -webkit-background-clip: text;
34
+ -webkit-text-fill-color: transparent;
35
+ text-shadow: 0px 2px 4px rgba(0,0,0,0.1);
36
+ }
37
+ .sub-header {
38
+ font-size: 1.5rem;
39
+ color: #2e86ab;
40
+ margin-bottom: 1rem;
41
+ font-weight: 600;
42
+ border-bottom: 2px solid #1f77b4;
43
+ padding-bottom: 0.5rem;
44
  }
45
+ .section-container {
46
+ background: white;
47
+ padding: 25px;
48
+ border-radius: 15px;
49
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
50
+ margin-bottom: 25px;
51
+ border: 1px solid #e0e0e0;
52
+ }
53
+ .metric-card {
54
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
55
+ color: white;
56
+ padding: 20px;
57
+ border-radius: 12px;
58
+ text-align: center;
59
+ box-shadow: 0 4px 8px rgba(0,0,0,0.2);
60
  }
61
  .risk-high {
62
+ background: linear-gradient(135deg, #ff6b6b, #ee5a52);
63
+ color: white;
64
+ padding: 20px;
65
+ border-radius: 12px;
66
+ border-left: 6px solid #dc3545;
67
+ box-shadow: 0 4px 8px rgba(220,53,69,0.3);
68
  }
69
  .risk-medium {
70
+ background: linear-gradient(135deg, #ffd93d, #ffcd3c);
71
+ color: #333;
72
+ padding: 20px;
73
+ border-radius: 12px;
74
+ border-left: 6px solid #ffc107;
75
+ box-shadow: 0 4px 8px rgba(255,193,7,0.3);
76
  }
77
  .risk-low {
78
+ background: linear-gradient(135deg, #6bcf7f, #28a745);
79
+ color: white;
80
+ padding: 20px;
81
+ border-radius: 12px;
82
+ border-left: 6px solid #20c997;
83
+ box-shadow: 0 4px 8px rgba(40,167,69,0.3);
84
  }
85
  .priority-box {
86
+ border: 3px solid #2E86AB;
87
+ padding: 25px;
88
+ border-radius: 15px;
89
+ margin: 15px 0;
90
+ background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
91
+ box-shadow: 0 6px 15px rgba(0,0,0,0.1);
92
  }
93
  .stButton button {
94
  width: 100%;
95
+ background: linear-gradient(45deg, #1f77b4, #2e86ab);
96
  color: white;
97
  font-weight: bold;
98
  border: none;
99
+ padding: 14px 28px;
100
+ border-radius: 10px;
101
+ font-size: 1.1rem;
102
+ transition: all 0.3s ease;
103
+ box-shadow: 0 4px 8px rgba(31,119,180,0.3);
104
  }
105
+ .stButton button:hover {
106
+ transform: translateY(-2px);
107
+ box-shadow: 0 6px 12px rgba(31,119,180,0.4);
108
+ background: linear-gradient(45deg, #2e86ab, #1f77b4);
109
+ }
110
+ .dataframe {
111
+ border-radius: 10px;
112
+ overflow: hidden;
113
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
114
  }
115
  .dataframe th {
116
+ background: linear-gradient(135deg, #1f77b4, #2e86ab);
117
  color: white;
118
  font-weight: bold;
119
+ padding: 12px;
120
+ }
121
+ .dataframe td {
122
+ padding: 10px;
123
+ border-bottom: 1px solid #e0e0e0;
124
  }
125
  .dataframe tr:nth-child(even) {
126
+ background-color: #f8f9fa;
127
+ }
128
+ .dataframe tr:hover {
129
+ background-color: #e3f2fd;
130
+ }
131
+ .sidebar .sidebar-content {
132
+ background: linear-gradient(180deg, #1f77b4 0%, #2e86ab 100%);
133
+ }
134
+ .chat-message {
135
+ padding: 1rem;
136
+ border-radius: 0.5rem;
137
+ margin-bottom: 1rem;
138
+ display: flex;
139
+ flex-direction: column;
140
+ }
141
+ .chat-message.user {
142
+ background-color: #2b5797;
143
+ color: white;
144
+ margin-left: 20%;
145
+ }
146
+ .chat-message.assistant {
147
+ background-color: #f0f2f6;
148
+ color: #333;
149
+ margin-right: 20%;
150
  }
151
  </style>
152
  """, unsafe_allow_html=True)
153
 
154
  # Initialize session state
155
  def init_session_state():
 
 
156
  if 'patient_data' not in st.session_state:
157
  st.session_state.patient_data = {}
158
  if 'risk_scores' not in st.session_state:
159
  st.session_state.risk_scores = {}
160
+ if 'assessment_history' not in st.session_state:
161
+ st.session_state.assessment_history = []
 
 
162
 
163
  # Load trained models
164
  @st.cache_resource(show_spinner=False)
 
215
  # Return rule-based fallback
216
  return "rule_based", "rule_based", "rule_based"
217
 
218
+ class HealthcareAssistant:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  def __init__(self):
220
+ # Comprehensive medical knowledge base
221
+ self.medical_knowledge = {
222
+ 'heart_health': {
223
+ 'English': """
224
+ **Heart Health Management Guidelines:**
225
+
226
+ **Risk Factors to Monitor:**
227
+ High blood pressure (>140/90 mmHg)
228
+ Elevated cholesterol levels (>200 mg/dL)
229
+ • Smoking and tobacco use
230
+ Diabetes and pre-diabetes
231
+ Obesity (BMI > 30)
232
+ • Physical inactivity
233
+ Family history of heart disease
234
+
235
+ **Preventive Measures:**
236
+ • Regular exercise (30 mins, 5 days/week)
237
+ Heart-healthy diet (Mediterranean diet recommended)
238
+ • Maintain healthy weight
239
+ Regular blood pressure monitoring
240
+ Annual cholesterol checks
241
+ Stress management techniques
242
+
243
+ **Warning Signs - Seek Immediate Care:**
244
+ Chest pain or discomfort
245
+ Shortness of breath
246
+ • Pain radiating to arm, neck, or jaw
247
+ Dizziness or fainting
248
+ Irregular heartbeat
249
+ """,
250
+ 'Urdu': """
251
+ **دل کی صحت کے انتظام کے رہنما اصول:**
252
+
253
+ **نگرانی کرنے والے خطرے کے عوامل:**
254
+ ہائی بلڈ پریشر (>140/90 mmHg)
255
+ کولیسٹرول کی بلند سطح (>200 mg/dL)
256
+ • سگریٹ نوشی اور تمباکو کا استعمال
257
+ ذیابیطس اور پیش ذیابیطس
258
+ موٹاپا (BMI > 30)
259
+ • جسمانی غیر فعالیت
260
+ دل کی بیماری کی خاندانی تاریخ
261
+
262
+ **احتیاطی تدابیر:**
263
+ باقاعدہ ورزش (30 منٹ، ہفتے میں 5 دن)
264
+ دل کی صحت کے لیے مفید غذا (بحیرہ روم کی غذا تجویز کردہ)
265
+ • صحت مند وزن برقرار رکھیں
266
+ بلڈ پریشر کی باقاعدہ نگرانی
267
+ سالانہ کولیسٹرول چیک
268
+ • تناؤ کے انتظام کی تکنیکیں
269
+
270
+ **انتباہی علامات - فوری دیکھ بھال حاصل کریں:**
271
+ • سینے میں درد یا بے چینی
272
+ سانس لینے میں دشواری
273
+ • بازو، گردن یا جبڑے میں پھیلنے والا درد
274
+ چکر آنا یا بیہوش ہونا
275
+ بے قاعدہ دل کی دھڑکن
276
+ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  },
278
  'diabetes': {
279
+ 'English': """
280
+ **Diabetes Management Protocol:**
281
+
282
+ **Key Monitoring Parameters:**
283
+ • Fasting blood sugar: 80-130 mg/dL
284
+ • Post-meal blood sugar: <180 mg/dL
285
+ • HbA1c: <7.0%
286
+ • Blood pressure: <140/90 mmHg
287
+ • Cholesterol levels (LDL <100 mg/dL)
288
+
289
+ **Management Strategies:**
290
+ • Regular glucose monitoring
291
+ • Balanced carbohydrate intake
292
+ • Regular physical activity
293
+ • Medication adherence
294
+ • Foot care and examination
295
+ • Regular eye examinations
296
+
297
+ **Emergency Symptoms:**
298
+ • Blood sugar >300 mg/dL or <70 mg/dL
299
+ • Confusion or disorientation
300
+ • Excessive thirst and urination
301
+ • Blurred vision
302
+ • Fruity breath odor
303
+ """,
304
+ 'Urdu': """
305
+ **ذیابیطس کے انتظام کا پروٹوکول:**
306
+
307
+ **اہم نگرانی کے پیرامیٹرز:**
308
+ • فاسٹنگ بلڈ شوگر: 80-130 mg/dL
309
+ • کھانے کے بعد بلڈ شوگر: <180 mg/dL
310
+ • HbA1c: <7.0%
311
+ • بلڈ پریشر: <140/90 mmHg
312
+ • کولیسٹرول کی سطح (LDL <100 mg/dL)
313
+
314
+ **انتظام کی حکمت عملی:**
315
+ • گلوکوز کی باقاعدہ نگرانی
316
+ • متوازن کاربوہائیڈریٹ کی مقدار
317
+ • باقاعدہ جسمانی سرگرمی
318
+ • ادویات کی پابندی
319
+ • پاؤں کی دیکھ بھال اور معائنہ
320
+ • باقاعدہ آنکھوں کے معائنے
321
+
322
+ **ہنگامی علامات:**
323
+ • بلڈ شوگر >300 mg/dL یا <70 mg/dL
324
+ • الجھن یا بے ترتیبی
325
+ • ضرورت سے زیادہ پیاس اور پیشاب
326
+ • دھندلا نظر آنا
327
+ • پھل کی سی بو والی سانس
328
+ """
329
  },
330
  'hypertension': {
331
+ 'English': """
332
+ **Hypertension Control Guidelines:**
333
+
334
+ **Blood Pressure Classification:**
335
+ Normal: <120/80 mmHg
336
+ Elevated: 120-129/<80 mmHg
337
+ • Stage 1: 130-139/80-89 mmHg
338
+ • Stage 2: ≥140/90 mmHg
339
+
340
+ **Lifestyle Modifications:**
341
+ • DASH diet (Dietary Approaches to Stop Hypertension)
342
+ • Sodium restriction (<2,300 mg/day)
343
+ • Regular aerobic exercise
344
+ • Weight management
345
+ • Alcohol moderation
346
+ • Stress reduction techniques
347
+
348
+ **Monitoring Schedule:**
349
+ • Daily BP monitoring if uncontrolled
350
+ • Weekly if well-controlled
351
+ • Regular medication review
352
+ • Annual kidney function tests
353
+ """,
354
+ 'Urdu': """
355
+ **ہائی بلڈ پریشر کنٹرول گائیڈ لائنز:**
356
+
357
+ **بلڈ پریشر کی درجہ بندی:**
358
+ • نارمل: <120/80 mmHg
359
+ • بلند: 120-129/<80 mmHg
360
+ • اسٹیج 1: 130-139/80-89 mmHg
361
+ • اسٹیج 2: ≥140/90 mmHg
362
+
363
+ **طرز زندگی میں تبدیلیاں:**
364
+ • ڈیش ڈائٹ (ہائی بلڈ پریشر روکنے کے لیے غذائی طریقے)
365
+ • سوڈیم کی پابندی (<2,300 mg/day)
366
+ • باقاعدہ ایروبک ورزش
367
+ • وزن کا انتظام
368
+ • شراب میں اعتدال
369
+ • تناؤ میں کمی کی تکنیکیں
370
+
371
+ **نگرانی کا شیڈول:**
372
+ • روزانہ بی پی مانیٹرنگ اگر کنٹرول نہ ہو
373
+ • ہفتہ وار اگر اچھی طرح کنٹرول ہو
374
+ • ادویات کی باقاعدہ جائزہ
375
+ • سالانہ گردے کے فنکشن ٹیسٹ
376
+ """
377
  }
378
  }
379
 
380
+ def get_medical_advice(self, topic, language='English'):
381
+ """Provide structured medical advice based on topic"""
382
+ if topic in self.medical_knowledge:
383
+ return self.medical_knowledge[topic][language]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  else:
385
+ if language == 'English':
386
+ return "**General Health Advice:**\n\n• Maintain regular health check-ups\n• Follow a balanced diet\n• Stay physically active\n• Get adequate sleep (7-9 hours)\n• Manage stress effectively\n• Avoid smoking and limit alcohol\n• Stay hydrated with 8-10 glasses of water daily"
387
+ else:
388
+ return "**عام صحت کے مشورے:**\n\n• باقاعدہ صحت کی جانچ برقرار رکھیں\n• متوازن غذا کی پیروی کریں\n• جسمانی طور پر متحرک رہیں\n• مناسب نیند لیں (7-9 گھنٹے)\n• تناؤ کو مؤثر طریقے سے منظم کریں\n• تمباکو نوشی سے پرہیز کریں اور شراب کو محدود کریں\n• روزانہ 8-10 گلاس پانی پی کر ہائیڈریٹ رہیں"
389
 
390
  def calculate_priority_score(heart_risk, diabetes_risk, hypertension_risk):
391
  """Calculate integrated priority score with clinical weighting"""
 
511
 
512
  return heart_features, diabetes_features, hypertension_features
513
 
514
+ def create_patient_report(patient_data, risk_scores, language='English'):
515
+ """Generate comprehensive patient report"""
516
+ report = {}
517
+
518
+ if language == 'English':
519
+ report['header'] = "PATIENT ASSESSMENT REPORT"
520
+ report['patient_info'] = f"""
521
+ **Patient Details:**
522
+ - Name: {patient_data.get('name', 'Not provided')}
523
+ - Age: {patient_data.get('age', 'Not provided')} years
524
+ - Gender: {patient_data.get('gender', 'Not provided')}
525
+ - Contact: {patient_data.get('contact', 'Not provided')}
526
+ """
527
+
528
+ report['clinical_findings'] = f"""
529
+ **Clinical Parameters:**
530
+ - Blood Pressure: {patient_data.get('bp_systolic', 'N/A')}/{patient_data.get('bp_diastolic', 'N/A')} mmHg
531
+ - Heart Rate: {patient_data.get('heart_rate', 'N/A')} bpm
532
+ - Cholesterol: {patient_data.get('cholesterol', 'N/A')} mg/dL
533
+ - Glucose: {patient_data.get('glucose', 'N/A')} mg/dL
534
+ - BMI: {patient_data.get('bmi', 'N/A')}
535
+ """
536
+
537
+ report['risk_assessment'] = f"""
538
+ **Risk Assessment Results:**
539
+ - Heart Disease Risk: {risk_scores.get('heart', 0):.1%}
540
+ - Diabetes Risk: {risk_scores.get('diabetes', 0):.1%}
541
+ - Hypertension Risk: {risk_scores.get('hypertension', 0):.1%}
542
+ - Overall Priority Score: {risk_scores.get('priority', 0):.1%}
543
+ """
544
+
545
+ report['recommendation'] = f"""
546
+ **Clinical Recommendation:**
547
+ {risk_scores.get('recommendation', 'No recommendation available')}
548
+ """
549
+ else:
550
+ report['header'] = "مریض تشخیص رپورٹ"
551
+ report['patient_info'] = f"""
552
+ **مریض کی تفصیلات:**
553
+ - نام: {patient_data.get('name', 'فراہم نہیں کیا گیا')}
554
+ - عمر: {patient_data.get('age', 'فراہم نہیں کیا گیا')} سال
555
+ - جنس: {patient_data.get('gender', 'فراہم نہیں کیا گیا')}
556
+ - رابطہ: {patient_data.get('contact', 'فراہم نہیں کیا گیا')}
557
+ """
558
+
559
+ report['clinical_findings'] = f"""
560
+ **کلینیکل پیرامیٹرز:**
561
+ - بلڈ پریشر: {patient_data.get('bp_systolic', 'N/A')}/{patient_data.get('bp_diastolic', 'N/A')} mmHg
562
+ - دل کی دھڑکن: {patient_data.get('heart_rate', 'N/A')} bpm
563
+ - کولیسٹرول: {patient_data.get('cholesterol', 'N/A')} mg/dL
564
+ - گلوکوز: {patient_data.get('glucose', 'N/A')} mg/dL
565
+ - BMI: {patient_data.get('bmi', 'N/A')}
566
+ """
567
+
568
+ report['risk_assessment'] = f"""
569
+ **خطرے کے تشخیص کے نتائج:**
570
+ - دل کی بیماری کا خطرہ: {risk_scores.get('heart', 0):.1%}
571
+ - ذیابیطس کا خطرہ: {risk_scores.get('diabetes', 0):.1%}
572
+ - ہائی بلڈ پریشر کا خطرہ: {risk_scores.get('hypertension', 0):.1%}
573
+ - مجموعی ترجیحی اسکور: {risk_scores.get('priority', 0):.1%}
574
+ """
575
+
576
+ report['recommendation'] = f"""
577
+ **کلینیکل سفارش:**
578
+ {risk_scores.get('recommendation', 'کوئی سفارش دستیاب نہیں')}
579
+ """
580
+
581
+ return report
582
+
583
  def main():
584
  # Load custom CSS
585
  local_css()
 
589
  with st.spinner("🔄 Loading AI models..."):
590
  heart_model, diabetes_model, hypertension_model = load_models()
591
 
592
+ # Initialize healthcare assistant
593
+ healthcare_assistant = HealthcareAssistant()
594
 
595
+ # Professional sidebar
596
  with st.sidebar:
597
+ st.markdown("""
598
+ <div style='text-align: center; padding: 20px; background: linear-gradient(135deg, #1f77b4, #2e86ab);
599
+ border-radius: 15px; color: white; margin-bottom: 20px;'>
600
+ <h2 style='margin: 0; font-size: 1.8rem;'>🏥 AI-Priority OPD</h2>
601
+ <p style='margin: 5px 0; font-size: 0.9rem;'>Smart Patient Triage System</p>
602
+ </div>
603
+ """, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
604
 
605
+ # Language selector
606
  language = st.radio(
607
  "Select Language / زبان منتخب کریں",
608
  ["English", "Urdu"],
609
+ key="language_selector",
610
+ index=0
611
  )
612
 
613
  st.markdown("---")
614
 
615
+ # Quick actions
616
  if language == "English":
617
+ st.subheader("🚀 Quick Actions")
618
+ col1, col2 = st.columns(2)
619
+
620
+ with col1:
621
+ if st.button("🆕 New Patient", use_container_width=True):
622
+ st.session_state.patient_data = {}
623
+ st.session_state.risk_scores = {}
624
+ st.rerun()
625
+
626
+ with col2:
627
+ if st.button("📊 Dashboard", use_container_width=True):
628
+ st.rerun()
629
+
630
+ st.markdown("---")
631
+ st.subheader("📈 System Status")
632
+
633
+ # System metrics
634
+ metrics_col1, metrics_col2 = st.columns(2)
635
+
636
+ with metrics_col1:
637
+ st.metric("Models Loaded", "3/3", "100%")
638
+
639
+ with metrics_col2:
640
+ st.metric("Assessments", len(st.session_state.assessment_history))
641
+
642
+ st.info("✅ System Ready for Patient Assessment")
643
+
644
  else:
645
+ st.subheader("🚀 فوری اقدامات")
646
+ col1, col2 = st.columns(2)
647
+
648
+ with col1:
649
+ if st.button("🆕 نیا مریض", use_container_width=True):
650
+ st.session_state.patient_data = {}
651
+ st.session_state.risk_scores = {}
652
+ st.rerun()
653
+
654
+ with col2:
655
+ if st.button("📊 ڈیش بورڈ", use_container_width=True):
656
+ st.rerun()
657
+
658
+ st.markdown("---")
659
+ st.subheader("📈 سسٹم کی حالت")
660
+
661
+ # System metrics
662
+ metrics_col1, metrics_col2 = st.columns(2)
663
+
664
+ with metrics_col1:
665
+ st.metric("ماڈل لوڈ ہو گئے", "3/3", "100%")
666
+
667
+ with metrics_col2:
668
+ st.metric("تشخیص", len(st.session_state.assessment_history))
669
+
670
+ st.info("✅ سسٹم مریض کی تشخیص کے لیے تیار ہے")
671
 
672
+ # Main header with professional design
673
+ st.markdown("""
674
+ <div style='background: linear-gradient(135deg, #1f77b4, #2e86ab); padding: 30px;
675
+ border-radius: 15px; text-align: center; color: white; margin-bottom: 30px;
676
+ box-shadow: 0 8px 25px rgba(31,119,180,0.3);'>
677
+ <h1 class='main-header' style='color: white; margin: 0;'>🏥 AI-Priority OPD System</h1>
678
+ <p style='font-size: 1.2rem; margin: 10px 0 0 0; opacity: 0.9;'>
679
+ Smart Patient Triage and Priority Management for Healthcare Excellence
680
+ </p>
681
+ </div>
682
+ """, unsafe_allow_html=True)
683
 
684
  # Create tabs
685
  if language == "English":
686
+ tab_names = ["Patient Assessment", "Medical Guidelines", "Analytics Dashboard"]
687
  else:
688
+ tab_names = ["مریض تشخیص", "طبی رہنما خطوط", "تجزیاتی ڈیش بورڈ"]
689
 
690
+ tab1, tab2, tab3 = st.tabs(tab_names)
691
 
692
  with tab1:
693
  # Patient Assessment Form
694
+ st.markdown('<div class="section-container">', unsafe_allow_html=True)
695
+
696
  if language == "English":
697
+ st.markdown('<div class="sub-header">👨‍⚕️ Comprehensive Patient Assessment</div>', unsafe_allow_html=True)
698
+ st.write("Complete the following form for comprehensive patient risk assessment and priority scoring")
699
  else:
700
+ st.markdown('<div class="sub-header">👨‍⚕️ جامع مریض تشخیص</div>', unsafe_allow_html=True)
701
+ st.write("جامع مریض کے خطرے کی تشخیص اور ترجیحی اسکورنگ کے لیے درج ذیل فارم کو مکمل کریں")
702
 
703
  with st.form("patient_assessment_form"):
704
  col1, col2 = st.columns(2)
 
706
  with col1:
707
  # Basic Information
708
  if language == "English":
709
+ st.markdown("**Personal Information**")
710
  name = st.text_input("Full Name", placeholder="Enter patient's full name")
711
  age = st.number_input("Age", min_value=1, max_value=120, value=45,
712
  help="Patient's age in years")
713
  gender = st.selectbox("Gender", ["Male", "Female", "Other"])
714
  contact = st.text_input("Contact Number", placeholder="03XX-XXXXXXX")
715
  else:
716
+ st.markdown("**ذاتی معلومات**")
717
  name = st.text_input("مکمل نام", placeholder="مریض کا مکمل نام درج کریں")
718
  age = st.number_input("عمر", min_value=1, max_value=120, value=45,
719
  help="مریض کی عمر سالوں میں")
 
723
  with col2:
724
  # Vital Signs
725
  if language == "English":
726
+ st.markdown("**Clinical Parameters**")
727
  bp_systolic = st.number_input("Blood Pressure (systolic)",
728
  min_value=70, max_value=250, value=120,
729
  help="Systolic blood pressure in mmHg")
 
739
  min_value=50, max_value=500, value=95)
740
  bmi = st.slider("BMI", min_value=15.0, max_value=40.0, value=23.5, step=0.1)
741
  else:
742
+ st.markdown("**کلینیکل پیرامیٹرز**")
743
  bp_systolic = st.number_input("بلڈ پریشر (سسٹولک)",
744
  min_value=70, max_value=250, value=120,
745
  help="سسٹولک بلڈ پریشر mmHg میں")
 
757
 
758
  # Symptoms Section
759
  if language == "English":
760
+ st.markdown("**Reported Symptoms**")
761
  col3, col4 = st.columns(2)
762
  with col3:
763
  chest_pain = st.checkbox("Chest Pain or Discomfort")
 
768
  dizziness = st.checkbox("Dizziness or Lightheadedness")
769
  blurred_vision = st.checkbox("Blurred Vision")
770
  else:
771
+ st.markdown("**رپورٹ کردہ علامات**")
772
  col3, col4 = st.columns(2)
773
  with col3:
774
  chest_pain = st.checkbox("سینے میں درد یا بے چینی")
 
807
  'blurred_vision': 1 if blurred_vision else 0
808
  }
809
 
810
+ # Store patient data
811
+ st.session_state.patient_data = {
812
+ 'name': name,
813
+ 'age': age,
814
+ 'gender': gender,
815
+ 'contact': contact,
816
+ 'bp_systolic': bp_systolic,
817
+ 'bp_diastolic': bp_diastolic,
818
+ 'heart_rate': heart_rate,
819
+ 'cholesterol': cholesterol,
820
+ 'glucose': glucose,
821
+ 'bmi': bmi,
822
+ 'symptoms': symptoms_dict
823
+ }
824
+
825
  # Get predictions based on available models
826
  if heart_model != "rule_based" and diabetes_model != "rule_based" and hypertension_model != "rule_based":
827
  # Use trained models
 
866
  'recommendation': recommendation,
867
  'level': priority_level
868
  }
869
+
870
+ # Add to assessment history
871
+ st.session_state.assessment_history.append({
872
+ 'timestamp': datetime.now(),
873
+ 'patient_data': st.session_state.patient_data.copy(),
874
+ 'risk_scores': st.session_state.risk_scores.copy()
875
+ })
876
 
877
  # Display results
878
  st.markdown("---")
 
880
 
881
  # Risk Scores Visualization
882
  if language == "English":
883
+ st.markdown('<div class="sub-header">📊 Disease Risk Assessment Dashboard</div>', unsafe_allow_html=True)
884
  else:
885
+ st.markdown('<div class="sub-header">📊 بیماری کے خطرے کی تشخیص ڈیش بورڈ</div>', unsafe_allow_html=True)
886
 
887
  col5, col6, col7, col8 = st.columns(4)
888
 
 
949
 
950
  st.markdown('</div>', unsafe_allow_html=True)
951
 
952
+ # Generate and display patient report
953
+ if language == "English":
954
+ st.markdown('<div class="sub-header">📋 Patient Assessment Report</div>', unsafe_allow_html=True)
955
+ else:
956
+ st.markdown('<div class="sub-header">📋 مریض تشخیص رپورٹ</div>', unsafe_allow_html=True)
957
+
958
+ report = create_patient_report(st.session_state.patient_data, st.session_state.risk_scores, language)
959
+
960
+ with st.expander("View Complete Patient Report" if language == "English" else "مکمل مریض رپورٹ دیکھیں", expanded=True):
961
+ st.markdown(f"**{report['header']}**")
962
+ st.markdown(report['patient_info'])
963
+ st.markdown(report['clinical_findings'])
964
+ st.markdown(report['risk_assessment'])
965
+ st.markdown(report['recommendation'])
966
+
967
  except Exception as e:
968
  st.error(f"❌ Error in risk assessment: {str(e)}")
969
+
970
+ st.markdown('</div>', unsafe_allow_html=True)
971
 
972
  with tab2:
973
+ # Medical Guidelines
974
+ st.markdown('<div class="section-container">', unsafe_allow_html=True)
975
+
976
  if language == "English":
977
+ st.markdown('<div class="sub-header">📚 Medical Guidelines & Health Information</div>', unsafe_allow_html=True)
978
+ st.write("Access comprehensive medical guidelines and health information for better patient care")
979
  else:
980
+ st.markdown('<div class="sub-header">📚 طبی رہنما خطوط اور صحت کی معلومات</div>', unsafe_allow_html=True)
981
+ st.write("بہتر مریض کی دیکھ بھال کے لیے جامع طبی رہنما خطوط اور صحت کی معلومات تک رسائی حاصل کریں")
 
 
 
 
 
 
982
 
983
+ # Medical topics selection
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
984
  if language == "English":
985
+ topic = st.selectbox(
986
+ "Select Medical Topic",
987
+ ["Heart Health", "Diabetes Management", "Hypertension Control", "General Health"]
988
+ )
989
  else:
990
+ topic = st.selectbox(
991
+ "طبی موضوع منتخب کریں",
992
+ ["دل کی صحت", "ذیابیطس کا انتظام", "ہائی بلڈ پریشر کنٹرول", "عام صحت"]
993
+ )
994
 
995
+ # Display medical information based on selected topic
996
+ if topic == "Heart Health" or topic == "دل کی صحت":
997
+ advice = healthcare_assistant.get_medical_advice('heart_health', language)
998
+ elif topic == "Diabetes Management" or topic == "ذیابیطس کا انتظام":
999
+ advice = healthcare_assistant.get_medical_advice('diabetes', language)
1000
+ elif topic == "Hypertension Control" or topic == "ہائی بلڈ پریشر کنٹرول":
1001
+ advice = healthcare_assistant.get_medical_advice('hypertension', language)
1002
+ else:
1003
+ advice = healthcare_assistant.get_medical_advice('general', language)
1004
 
1005
+ st.markdown(advice)
1006
+
1007
+ st.markdown('</div>', unsafe_allow_html=True)
1008
+
1009
+ with tab3:
1010
+ # Analytics Dashboard
1011
+ st.markdown('<div class="section-container">', unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
1012
 
 
1013
  if language == "English":
1014
+ st.markdown('<div class="sub-header">📈 System Analytics & Performance Dashboard</div>', unsafe_allow_html=True)
1015
+ st.write("Comprehensive analytics and performance metrics for the OPD system")
1016
  else:
1017
+ st.markdown('<div class="sub-header">📈 سسٹم تجزیات اور کارکردگی ڈیش بورڈ</div>', unsafe_allow_html=True)
1018
+ st.write("OPD سسٹم کے لیے جامع تجزیات اور کارکردگی کے پیمانے")
1019
 
1020
+ # Real-time performance metrics
1021
+ col9, col10, col11, col12 = st.columns(4)
1022
 
1023
+ with col9:
1024
+ st.markdown('<div class="metric-card">', unsafe_allow_html=True)
1025
+ if language == "English":
1026
+ st.metric("Total Assessments", len(st.session_state.assessment_history), "Patients")
1027
+ else:
1028
+ st.metric("کل تشخیص", len(st.session_state.assessment_history), "مریض")
1029
+ st.markdown('</div>', unsafe_allow_html=True)
1030
 
1031
+ with col10:
1032
+ st.markdown('<div class="metric-card">', unsafe_allow_html=True)
1033
+ if language == "English":
1034
+ st.metric("System Uptime", "99.8%", "0.2%")
1035
+ else:
1036
+ st.metric("سسٹم اپ ٹائم", "99.8%", "0.2%")
1037
+ st.markdown('</div>', unsafe_allow_html=True)
1038
 
1039
+ with col11:
1040
+ st.markdown('<div class="metric-card">', unsafe_allow_html=True)
1041
+ if language == "English":
1042
+ st.metric("Model Accuracy", "96.2%", "AI Models")
1043
+ else:
1044
+ st.metric("ماڈل درستگی", "96.2%", "AI ماڈل")
1045
+ st.markdown('</div>', unsafe_allow_html=True)
 
 
 
 
 
 
 
1046
 
1047
+ with col12:
1048
+ st.markdown('<div class="metric-card">', unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
1049
  if language == "English":
1050
+ st.metric("Avg. Processing", "< 2s", "Fast")
1051
  else:
1052
+ st.metric("اوسط پروسیسنگ", "< 2s", "تیز")
1053
+ st.markdown('</div>', unsafe_allow_html=True)
1054
 
1055
  # Analytics Charts
1056
+ if st.session_state.assessment_history:
1057
  col_chart1, col_chart2 = st.columns(2)
1058
 
1059
  with col_chart1:
1060
  if language == "English":
1061
+ st.subheader("Risk Distribution Analysis")
1062
  else:
1063
+ st.subheader("خطرے کی تقسیم کا تجزیہ")
1064
 
1065
+ # Get the latest assessment
1066
+ latest_assessment = st.session_state.assessment_history[-1]
1067
  risk_data = pd.DataFrame({
1068
  'Condition': ['Heart Disease', 'Diabetes', 'Hypertension'],
1069
  'Risk Score': [
1070
+ latest_assessment['risk_scores']['heart'],
1071
+ latest_assessment['risk_scores']['diabetes'],
1072
+ latest_assessment['risk_scores']['hypertension']
1073
  ]
1074
  })
1075
 
1076
  fig = px.bar(risk_data, x='Condition', y='Risk Score',
1077
+ color='Risk Score', color_continuous_scale='RdYlGn_r',
1078
+ title="Current Patient Risk Distribution")
1079
  st.plotly_chart(fig, use_container_width=True)
1080
 
1081
  with col_chart2:
1082
  if language == "English":
1083
+ st.subheader("Priority Level Distribution")
1084
  else:
1085
+ st.subheader("ترجیحی سطح کی تقسیم")
 
 
 
 
 
 
 
1086
 
1087
+ # Calculate priority distribution from history
1088
+ if len(st.session_state.assessment_history) > 1:
1089
+ priorities = [assess['risk_scores']['level'] for assess in st.session_state.assessment_history]
1090
+ priority_counts = pd.Series(priorities).value_counts()
1091
+
1092
+ fig_pie = px.pie(values=priority_counts.values,
1093
+ names=priority_counts.index,
1094
+ title="Historical Priority Distribution")
1095
+ st.plotly_chart(fig_pie, use_container_width=True)
1096
+ else:
1097
+ if language == "English":
1098
+ st.info("Complete more assessments to view priority distribution")
1099
+ else:
1100
+ st.info("ترجیحی تقسیم دیکھنے کے لیے مزید تشخیص مکمل کریں")
1101
+
1102
+ # Assessment History Table
1103
+ if language == "English":
1104
+ st.subheader("Assessment History")
1105
+ else:
1106
+ st.subheader("تشخیص کی تاریخ")
1107
+
1108
+ history_data = []
1109
+ for i, assessment in enumerate(st.session_state.assessment_history[-5:]): # Show last 5
1110
+ history_data.append({
1111
+ 'Date': assessment['timestamp'].strftime('%Y-%m-%d %H:%M'),
1112
+ 'Patient': assessment['patient_data'].get('name', 'Unknown'),
1113
+ 'Heart Risk': f"{assessment['risk_scores']['heart']:.1%}",
1114
+ 'Diabetes Risk': f"{assessment['risk_scores']['diabetes']:.1%}",
1115
+ 'Priority': assessment['risk_scores']['level']
1116
+ })
1117
+
1118
+ if history_data:
1119
+ df_history = pd.DataFrame(history_data)
1120
+ st.dataframe(df_history, use_container_width=True)
1121
+ else:
1122
+ if language == "English":
1123
+ st.info("No assessment history available")
1124
+ else:
1125
+ st.info("تشخیص کی تاریخ دستیاب نہیں ہے")
1126
+
1127
+ else:
1128
+ if language == "English":
1129
+ st.info("👆 Complete patient assessments to view analytics and performance metrics")
1130
+ else:
1131
+ st.info("👆 تجزیات اور کارکردگی کے پیمانے دیکھنے کے لیے مریض کی تشخیص مکمل کریں")
1132
+
1133
+ st.markdown('</div>', unsafe_allow_html=True)
1134
 
1135
  if __name__ == "__main__":
1136
  main()