import streamlit as st
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from database import init_db, add_medication, get_all_medications
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
import seaborn as sns
import base64
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier, IsolationForest
# Initialize the database
init_db()
# Set page config
st.set_page_config(
page_title="Medication Tracker",
page_icon="💊",
layout="centered",
initial_sidebar_state="expanded",
)
# Custom CSS for glass style UI
st.markdown(
"""
""",
unsafe_allow_html=True
)
st.markdown('
', unsafe_allow_html=True)
st.markdown("
Medication Tracker 💊
", unsafe_allow_html=True)
st.markdown("
Track your prescription medications easily and get helpful insights.
", unsafe_allow_html=True)
# Form to log medication
st.markdown('
', unsafe_allow_html=True)
st.markdown("
Log Your Medication
", unsafe_allow_html=True)
with st.form(key='log_medication'):
medication_name = st.text_input("Medication Name", key='medication_name', placeholder="e.g., Aspirin")
dosage = st.text_input("Dosage (e.g., 500 mg)", key='dosage', placeholder="e.g., 500 mg")
time_of_day = st.selectbox("Time of Day", ["Morning", "Afternoon", "Evening", "Night"], key='time_of_day')
date = st.date_input("Date", datetime.today(), key='date')
submit_button = st.form_submit_button(label='Log Medication')
if submit_button and medication_name and dosage:
add_medication(medication_name, dosage, time_of_day, date)
st.success(f"Logged: {medication_name} - {dosage} at {time_of_day} on {date}")
st.markdown('', unsafe_allow_html=True)
# Display logged medications
st.markdown('
', unsafe_allow_html=True)
st.markdown("
Logged Medications
", unsafe_allow_html=True)
medications = get_all_medications()
if not medications:
st.markdown("No medications logged yet.", unsafe_allow_html=True)
else:
for med in medications:
st.markdown(f'
{med[1]}
Dosage: {med[2]}
Time: {med[3]}
Date: {med[4]}
', unsafe_allow_html=True)
st.markdown('
', unsafe_allow_html=True)
# Provide insights and data visualization
st.markdown('
', unsafe_allow_html=True)
st.markdown("
Insights and Data Visualization
", unsafe_allow_html=True)
if medications:
df = pd.DataFrame(medications, columns=["ID", "Medication", "Dosage", "Time", "Date"])
# Convert Dosage to numeric
df['Dosage'] = df['Dosage'].str.extract('(\d+)').astype(float)
most_common_med = df['Medication'].mode()[0]
st.markdown(f"Most frequently taken medication: {most_common_med}", unsafe_allow_html=True)
avg_dosage_time = df.groupby('Time').size().idxmax()
st.markdown(f"Most common time of day for taking medications: {avg_dosage_time}", unsafe_allow_html=True)
st.markdown("Take your medications consistently at the same time each day to maintain stable drug levels in your body.", unsafe_allow_html=True)
st.markdown("If you have multiple medications, consult your healthcare provider to ensure there are no adverse interactions.", unsafe_allow_html=True)
# Visualization
st.markdown("
Medication Intake Over Time
", unsafe_allow_html=True)
df['Date'] = pd.to_datetime(df['Date'])
fig, ax = plt.subplots()
for key, grp in df.groupby(['Medication']):
ax = grp.plot(ax=ax, kind='line', x='Date', y='Dosage', label=key)
date_form = DateFormatter("%Y-%m-%d")
ax.xaxis.set_major_formatter(date_form)
plt.xlabel("Date")
plt.ylabel("Dosage (mg)")
plt.title("Medication Intake Over Time")
plt.legend(title='Medication')
st.pyplot(fig)
# Data export
csv = df.to_csv(index=False)
b64 = base64.b64encode(csv.encode()).decode() # B64 encoding
href = f'
Download CSV'
st.markdown(href, unsafe_allow_html=True)
# AI Prediction: Predicting missed doses
st.markdown("
Missed Dose Prediction
", unsafe_allow_html=True)
df['Missed'] = np.random.choice([0, 1], size=len(df)) # Simulate missed doses for training
# Prepare the data
X = df[['Dosage', 'Time']].replace({"Morning": 0, "Afternoon": 1, "Evening": 2, "Night": 3})
y = df['Missed']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Train the model
model = GradientBoostingClassifier()
model.fit(X_train, y_train)
# Predict the probability of missing the next dose
user_dosage = st.number_input('Enter your dosage for the next dose', value=0)
user_time = st.selectbox('Select the time of day for the next dose', ["Morning", "Afternoon", "Evening", "Night"])
user_time_encoded = ["Morning", "Afternoon", "Evening", "Night"].index(user_time)
if st.button('Predict Missed Dose'):
user_data = pd.DataFrame({'Dosage': [user_dosage], 'Time': [user_time_encoded]})
missed_prob = model.predict_proba(user_data)[:, 1][0]
st.markdown(f"**Probability of missing the next dose: {missed_prob:.2f}**")
# Medication Interaction Warnings
st.markdown("
Medication Interaction Warnings
", unsafe_allow_html=True)
interactions = {
"Aspirin": ["Warfarin", "Ibuprofen"],
"Ibuprofen": ["Aspirin", "Warfarin"],
"Warfarin": ["Aspirin", "Ibuprofen"],
}
user_medications = st.multiselect(
'Select your current medications',
list(interactions.keys())
)
potential_interactions = []
for med in user_medications:
for interaction in interactions.get(med, []):
if interaction in user_medications and interaction not in potential_interactions:
potential_interactions.append(interaction)
if potential_interactions:
st.warning(f"Potential interactions detected: {', '.join(potential_interactions)}")
else:
st.success("No interactions detected.")
# Adaptive Reminders (Simulated)
st.markdown("
Adaptive Reminders
", unsafe_allow_html=True)
reminder_times = {
"Morning": 8,
"Afternoon": 13,
"Evening": 18,
"Night": 22
}
def adaptive_reminder(user_time, success):
reminder_times[user_time] = reminder_times.get(user_time, 0) + (1 if success else -1)
return reminder_times[user_time]
if st.button('Simulate Reminder'):
success = np.random.choice([True, False]) # Simulate user response to reminder
new_time = adaptive_reminder(user_time, success)
st.markdown(f"Adaptive reminder time for {user_time} is now set to {new_time}:00")
# Anomaly Detection in Medication Patterns
st.markdown("
Anomaly Detection
", unsafe_allow_html=True)
if len(df) > 10: # Ensure enough data for anomaly detection
isolation_forest = IsolationForest(contamination=0.1)
df['Anomaly'] = isolation_forest.fit_predict(df[['Dosage']])
anomalies = df[df['Anomaly'] == -1]
if not anomalies.empty:
st.markdown("### Anomalies Detected:")
st.dataframe(anomalies[['Medication', 'Dosage', 'Time', 'Date']])
else:
st.markdown("No anomalies detected in your medication patterns.")
st.markdown('
', unsafe_allow_html=True)
# Footer
st.markdown("
", unsafe_allow_html=True)
st.markdown("
Disclaimer: This app is for tracking purposes only. Always consult with your healthcare provider for medical advice.
", unsafe_allow_html=True)
st.markdown('
', unsafe_allow_html=True)