140 lines
4.8 KiB
Python
140 lines
4.8 KiB
Python
from flask import Flask, render_template, request, redirect, url_for
|
|
import sqlite3
|
|
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
import matplotlib
|
|
import io
|
|
import base64
|
|
from datetime import datetime, timedelta
|
|
import os
|
|
|
|
app = Flask(__name__)
|
|
|
|
# Pharmacokinetics parameters (in minutes)
|
|
# ln(2) / (Half-life-in-minutes)
|
|
CAFFEINE_ABSORPTION_RATE = 0.02 # per minute (half-life ~35 min)
|
|
CAFFEINE_ELIMINATION_RATE = 0.0023 # per minute (half-life ~5 hours)
|
|
AMPHETAMINE_ABSORPTION_RATE = 0.02 # per minute (half-life ~30 min)
|
|
AMPHETAMINE_ELIMINATION_RATE = 0.0013 # per minute (half-life ~9 hours)
|
|
|
|
# Initialize database
|
|
def init_db():
|
|
conn = sqlite3.connect('stimulants.db')
|
|
c = conn.cursor()
|
|
c.execute('''CREATE TABLE IF NOT EXISTS doses
|
|
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
timestamp DATETIME,
|
|
type TEXT,
|
|
amount INTEGER)''')
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
# Calculate stimulant amount at given time
|
|
def calculate_amount(doses, time, k_abs, k_elim):
|
|
total = 0
|
|
for dose in doses:
|
|
dose_time = datetime.strptime(dose[0], '%Y-%m-%d %H:%M:%S')
|
|
t = (time - dose_time).total_seconds() / 60 # convert to minutes
|
|
if t >= 0:
|
|
# One-compartment model with first-order absorption
|
|
total += dose[1] * (k_abs / (k_abs - k_elim)) * (
|
|
np.exp(-k_elim * t) - np.exp(-k_abs * t)
|
|
)
|
|
return total
|
|
|
|
# Generate graph for past 24 hours
|
|
def generate_graph():
|
|
# Get current time and 24 hours ago
|
|
now = datetime.now()
|
|
start_time = now - timedelta(hours=24)
|
|
|
|
# Create time points (every 10 minutes)
|
|
times = [start_time + timedelta(minutes=i*10) for i in range(144)]
|
|
|
|
# Get all doses from database
|
|
conn = sqlite3.connect('stimulants.db')
|
|
c = conn.cursor()
|
|
c.execute("SELECT timestamp, amount FROM doses WHERE type='caffeine'")
|
|
caffeine_doses = c.fetchall()
|
|
c.execute("SELECT timestamp, amount FROM doses WHERE type='amphetamine'")
|
|
amphetamine_doses = c.fetchall()
|
|
conn.close()
|
|
|
|
# Calculate amounts for each time point
|
|
caffeine_levels = [calculate_amount(caffeine_doses, t,
|
|
CAFFEINE_ABSORPTION_RATE,
|
|
CAFFEINE_ELIMINATION_RATE) for t in times]
|
|
amphetamine_levels = [calculate_amount(amphetamine_doses, t,
|
|
AMPHETAMINE_ABSORPTION_RATE,
|
|
AMPHETAMINE_ELIMINATION_RATE) for t in times]
|
|
|
|
# Create plot
|
|
plt.figure(figsize=(12, 6))
|
|
plt.plot(times, caffeine_levels, 'b-', label='Caffeine (mg)')
|
|
plt.plot(times, amphetamine_levels, 'r-', label='Amphetamine (mg)')
|
|
plt.xlabel('Time')
|
|
plt.ylabel('Estimated Amount (mg)')
|
|
plt.title('Stimulant Levels in Body (Past 24 Hours)')
|
|
plt.legend()
|
|
plt.grid(True)
|
|
|
|
# Format x-axis
|
|
ax = plt.gca()
|
|
ax.xaxis.set_major_locator(matplotlib.dates.HourLocator(interval=4))
|
|
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%H:%M'))
|
|
|
|
# Convert to base64 string
|
|
img = io.BytesIO()
|
|
plt.savefig(img, format='png')
|
|
img.seek(0)
|
|
graph_url = base64.b64encode(img.getvalue()).decode()
|
|
plt.close()
|
|
return graph_url
|
|
|
|
@app.route('/')
|
|
def index():
|
|
# Calculate current amounts
|
|
now = datetime.now()
|
|
|
|
conn = sqlite3.connect('stimulants.db')
|
|
c = conn.cursor()
|
|
c.execute("SELECT timestamp, amount FROM doses WHERE type='caffeine'")
|
|
caffeine_doses = c.fetchall()
|
|
c.execute("SELECT timestamp, amount FROM doses WHERE type='amphetamine'")
|
|
amphetamine_doses = c.fetchall()
|
|
conn.close()
|
|
|
|
caffeine_amount = calculate_amount(caffeine_doses, now,
|
|
CAFFEINE_ABSORPTION_RATE,
|
|
CAFFEINE_ELIMINATION_RATE)
|
|
amphetamine_amount = calculate_amount(amphetamine_doses, now,
|
|
AMPHETAMINE_ABSORPTION_RATE,
|
|
AMPHETAMINE_ELIMINATION_RATE)
|
|
|
|
# Generate graph
|
|
graph_url = generate_graph()
|
|
|
|
return render_template('index.html',
|
|
caffeine_amount=round(caffeine_amount, 2),
|
|
amphetamine_amount=round(amphetamine_amount, 2),
|
|
graph_url=graph_url)
|
|
|
|
@app.route('/add_dose', methods=['POST'])
|
|
def add_dose():
|
|
stim_type = request.form['type']
|
|
amount = 10 # Fixed 10mg amount
|
|
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
|
|
conn = sqlite3.connect('stimulants.db')
|
|
c = conn.cursor()
|
|
c.execute("INSERT INTO doses (timestamp, type, amount) VALUES (?, ?, ?)",
|
|
(timestamp, stim_type, amount))
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
return redirect(url_for('index'))
|
|
|
|
if __name__ == '__main__':
|
|
init_db()
|
|
app.run(debug=True)
|