med-tracker / app.py
dizzafizza1's picture
Update app.py
77ca00c verified
raw
history blame contribute delete
No virus
8.83 kB
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(
"""
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background-color: #f0f2f6;
color: #333;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 2rem;
background: rgba(255, 255, 255, 0.85);
border-radius: 16px;
backdrop-filter: blur(10px);
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
border: 1px solid rgba(255, 255, 255, 0.3);
}
.log-entry {
padding: 1rem;
margin-bottom: 1rem;
background: rgba(255, 255, 255, 0.9);
border-radius: 10px;
backdrop-filter: blur(5px);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.title {
text-align: center;
color: #007aff;
}
.subtitle {
text-align: center;
color: #333;
margin-bottom: 1.5rem;
}
</style>
""",
unsafe_allow_html=True
)
st.markdown('<div class="container">', unsafe_allow_html=True)
st.markdown("<h1 class='title'>Medication Tracker πŸ’Š</h1>", unsafe_allow_html=True)
st.markdown("<p class='subtitle'>Track your prescription medications easily and get helpful insights.</p>", unsafe_allow_html=True)
# Form to log medication
st.markdown('<div class="log-form">', unsafe_allow_html=True)
st.markdown("<h2>Log Your Medication</h2>", 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('</div>', unsafe_allow_html=True)
# Display logged medications
st.markdown('<div class="logged-medications">', unsafe_allow_html=True)
st.markdown("<h2>Logged Medications</h2>", 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'<div class="log-entry"><strong>{med[1]}</strong><br>Dosage: {med[2]}<br>Time: {med[3]}<br>Date: {med[4]}</div>', unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
# Provide insights and data visualization
st.markdown('<div class="insights">', unsafe_allow_html=True)
st.markdown("<h2>Insights and Data Visualization</h2>", 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("<h3>Medication Intake Over Time</h3>", 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'<a href="data:file/csv;base64,{b64}" download="medications.csv">Download CSV</a>'
st.markdown(href, unsafe_allow_html=True)
# AI Prediction: Predicting missed doses
st.markdown("<h3>Missed Dose Prediction</h3>", 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("<h3>Medication Interaction Warnings</h3>", 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("<h3>Adaptive Reminders</h3>", 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("<h3>Anomaly Detection</h3>", 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('</div>', unsafe_allow_html=True)
# Footer
st.markdown("<hr>", unsafe_allow_html=True)
st.markdown("<p><strong>Disclaimer:</strong> This app is for tracking purposes only. Always consult with your healthcare provider for medical advice.</p>", unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)