Polished program
This commit is contained in:
parent
4ed58bf2dc
commit
74e9e36c19
45
edit.py
Normal file
45
edit.py
Normal file
@ -0,0 +1,45 @@
|
||||
import sqlite3
|
||||
from datetime import datetime, timedelta
|
||||
import os
|
||||
|
||||
|
||||
|
||||
def displayDB(cursor):
|
||||
cursor.execute("SELECT * FROM doses")
|
||||
|
||||
for line in cursor:
|
||||
print(line)
|
||||
|
||||
def update(uid, timestamp, stim, mg, cursor):
|
||||
cursor.execute("UPDATE doses SET timestamp = ?, type = ?, amount = ? WHERE id = ?", (timestamp, stim, mg, uid))
|
||||
|
||||
def insert(timestamp, stim, mg, cursor):
|
||||
cursor.execute("INSERT INTO doses (timestamp, type, amount) VALUES (?,?,?)", (timestamp, stim, mg))
|
||||
|
||||
def delete(uid,cursor):
|
||||
cursor.execute("DELETE FROM doses WHERE id = ?", (uid,))
|
||||
|
||||
|
||||
def main():
|
||||
conn = sqlite3.connect('stimulants.db')
|
||||
c = conn.cursor()
|
||||
|
||||
timestamp = "2025-10-10 05:45:00"
|
||||
stim = "amphetamine"
|
||||
#stim = "caffeine"
|
||||
mg = 20
|
||||
|
||||
#update(1,timestamp,stim,mg,c)
|
||||
delete(6,c)
|
||||
#delete(2,c)
|
||||
insert("2025-10-09 13:00:00", stim, 20, c)
|
||||
insert("2025-10-09 13:00:00", "caffeine", 50, c)
|
||||
insert("2025-10-09 16:30:00", stim, 10, c)
|
||||
|
||||
displayDB(c)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
139
main.py
Normal file
139
main.py
Normal file
@ -0,0 +1,139 @@
|
||||
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.05 # per minute (half-life ~15 min)
|
||||
CAFFEINE_ELIMINATION_RATE = 0.0023 # per minute (half-life ~5 hours)
|
||||
AMPHETAMINE_ABSORPTION_RATE = 0.03 # per minute (half-life ~20 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)
|
||||
120
templates/index.html
Normal file
120
templates/index.html
Normal file
@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Stimulant Tracker</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background-color: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
text-align: center;
|
||||
}
|
||||
.stimulant-info {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.stimulant-box {
|
||||
background-color: #f9f9f9;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
width: 45%;
|
||||
}
|
||||
.stimulant-box h2 {
|
||||
margin-top: 0;
|
||||
color: #555;
|
||||
}
|
||||
.amount {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.caffeine { color: #0066cc; }
|
||||
.amphetamine { color: #cc0000; }
|
||||
.buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
margin: 30px 0;
|
||||
}
|
||||
button {
|
||||
padding: 12px 30px;
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
.caffeine-btn { background-color: #0066cc; }
|
||||
.amphetamine-btn { background-color: #cc0000; }
|
||||
button:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.graph-container {
|
||||
margin-top: 30px;
|
||||
}
|
||||
.graph-container img {
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.disclaimer {
|
||||
margin-top: 30px;
|
||||
padding: 15px;
|
||||
background-color: #fff8e1;
|
||||
border-left: 4px solid #ffc107;
|
||||
font-size: 0.9em;
|
||||
color: #856404;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Stimulant Tracker</h1>
|
||||
|
||||
<div class="stimulant-info">
|
||||
<div class="stimulant-box">
|
||||
<h2>Caffeine</h2>
|
||||
<div class="amount caffeine">{{ caffeine_amount }} mg</div>
|
||||
</div>
|
||||
<div class="stimulant-box">
|
||||
<h2>Amphetamine</h2>
|
||||
<div class="amount amphetamine">{{ amphetamine_amount }} mg</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<form action="/add_dose" method="post">
|
||||
<input type="hidden" name="type" value="caffeine">
|
||||
<button type="submit" class="caffeine-btn">Add 10mg Caffeine</button>
|
||||
</form>
|
||||
<form action="/add_dose" method="post">
|
||||
<input type="hidden" name="type" value="amphetamine">
|
||||
<button type="submit" class="amphetamine-btn">Add 10mg Amphetamine</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="graph-container">
|
||||
<h2>Stimulant Levels (Past 24 Hours)</h2>
|
||||
<img src="data:image/png;base64,{{ graph_url }}" alt="Stimulant Levels Graph">
|
||||
</div>
|
||||
|
||||
<div class="disclaimer">
|
||||
CAFFEINE_ABSORPTION_RATE half-life ~15 min, CAFFEINE_ELIMINATION_RATE half-life ~5 hours, AMPHETAMINE_ABSORPTION_RATE half-life ~20 min, AMPHETAMINE_ELIMINATION_RATE half-life ~9 hours
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user