update
This commit is contained in:
1051
Untitled.ipynb
1051
Untitled.ipynb
File diff suppressed because it is too large
Load Diff
114
analyze.py
114
analyze.py
@@ -1,46 +1,22 @@
|
|||||||
from pathlib import Path
|
|
||||||
from datetime import datetime
|
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from functools import reduce
|
from common import parse_foods_file, evaluate_food_entry
|
||||||
import re
|
|
||||||
import string
|
import string
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
from common import parse_foods_file
|
journal = json.load(open('journal.json'))
|
||||||
|
|
||||||
foods, recipes = parse_foods_file()
|
foods, recipes = parse_foods_file()
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
|
|
||||||
value, name = sys.argv[1:]
|
value, name = sys.argv[1:]
|
||||||
value = float(value.removesuffix('g'))
|
value = float(value.removesuffix('g'))
|
||||||
|
|
||||||
if name in recipes:
|
|
||||||
food = recipes[name]
|
|
||||||
|
|
||||||
if value == 0.0:
|
|
||||||
value = food['TOTAL']
|
|
||||||
|
|
||||||
food = {k: v*(value/food['TOTAL']) for k,v in food.items()}
|
|
||||||
elif name in foods:
|
|
||||||
if value == 0.0:
|
|
||||||
value = 100
|
|
||||||
|
|
||||||
food = {k: v*(value/100.0) for k,v in foods[name].items()}
|
|
||||||
else:
|
|
||||||
breakpoint()
|
|
||||||
print(f'ERROR: Invalid diet entry: {content}')
|
|
||||||
|
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
pprint(food)
|
pprint(evaluate_food_entry(foods, recipes, value, name))
|
||||||
|
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
|
|
||||||
entry_re = re.compile(r'^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) ', re.MULTILINE)
|
|
||||||
diet_re = re.compile(r'@diet (\d+g) ([a-zA-Z]+)')
|
|
||||||
|
|
||||||
total_entries = 0
|
total_entries = 0
|
||||||
total_words = 0
|
total_words = 0
|
||||||
word_frequency = Counter()
|
word_frequency = Counter()
|
||||||
@@ -56,14 +32,8 @@ diet_csv = [[
|
|||||||
'saturated_fat', 'sugar', 'fiber'
|
'saturated_fat', 'sugar', 'fiber'
|
||||||
]]
|
]]
|
||||||
|
|
||||||
output = open('diet', 'w')
|
for day, obj in journal.items():
|
||||||
|
daily_entries = len(obj['entries'])
|
||||||
for fpath in sorted((Path.home() / 'workspace' / 'journal').glob('*.md')):
|
|
||||||
day = fpath.stem
|
|
||||||
header, *tmp = entry_re.split(fpath.read_text())
|
|
||||||
entries = list(zip(tmp[::2], tmp[1::2]))
|
|
||||||
|
|
||||||
daily_entries = len(entries)
|
|
||||||
daily_words = 0
|
daily_words = 0
|
||||||
daily_calories = 0.0
|
daily_calories = 0.0
|
||||||
daily_protein = 0.0
|
daily_protein = 0.0
|
||||||
@@ -71,45 +41,25 @@ for fpath in sorted((Path.home() / 'workspace' / 'journal').glob('*.md')):
|
|||||||
daily_fat = 0.0
|
daily_fat = 0.0
|
||||||
daily_sugar = 0.0
|
daily_sugar = 0.0
|
||||||
|
|
||||||
output.write(f'-- {day}\n')
|
for entry in obj['entries']:
|
||||||
|
for block in entry['blocks']:
|
||||||
for (timestamp, content) in sorted(entries, key=lambda x: x[0]):
|
if isinstance(block, str):
|
||||||
ts_str = timestamp
|
words = ''.join(
|
||||||
timestamp = int(datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S').timestamp())
|
c if c in string.ascii_letters+"'" else ' '
|
||||||
|
for c in block.lower()
|
||||||
content = '\n'.join(
|
).split()
|
||||||
part.replace('\n', ' ')
|
|
||||||
for part in content.split('\n\n')
|
|
||||||
)
|
|
||||||
|
|
||||||
for diet in diet_re.finditer(content):
|
|
||||||
value, name = diet.groups()
|
|
||||||
output.write(f'{ts_str} {name} {value}\n')
|
|
||||||
|
|
||||||
value = float(value.removesuffix('g'))
|
|
||||||
|
|
||||||
|
|
||||||
if name in recipes:
|
|
||||||
food = recipes[name]
|
|
||||||
|
|
||||||
if value == 0.0:
|
|
||||||
value = food['TOTAL']
|
|
||||||
|
|
||||||
food = {k: v*(value/food['TOTAL']) for k,v in food.items()}
|
|
||||||
elif name in foods:
|
|
||||||
if value == 0.0:
|
|
||||||
value = 100
|
|
||||||
|
|
||||||
food = {k: v*(value/100.0) for k,v in foods[name].items()}
|
|
||||||
else:
|
|
||||||
breakpoint()
|
|
||||||
print(f'ERROR: Invalid diet entry: {content}')
|
|
||||||
continue
|
|
||||||
|
|
||||||
|
word_frequency.update(words)
|
||||||
|
|
||||||
|
entry_words = len(words)
|
||||||
|
daily_words += entry_words
|
||||||
|
elif block['type'] == 'diet':
|
||||||
|
name = block['food']
|
||||||
|
value = block['amount']
|
||||||
|
food = evaluate_food_entry(foods, recipes, value, name)
|
||||||
|
|
||||||
diet_csv.append((
|
diet_csv.append((
|
||||||
timestamp,
|
entry['timestamp'],
|
||||||
name,
|
name,
|
||||||
value,
|
value,
|
||||||
round(food.get('Energy', 0.0), 2),
|
round(food.get('Energy', 0.0), 2),
|
||||||
@@ -127,17 +77,7 @@ for fpath in sorted((Path.home() / 'workspace' / 'journal').glob('*.md')):
|
|||||||
daily_carbs += food.get('Carbs', 0.0)
|
daily_carbs += food.get('Carbs', 0.0)
|
||||||
daily_sugar += food.get('Sugar', 0.0)
|
daily_sugar += food.get('Sugar', 0.0)
|
||||||
|
|
||||||
words = ''.join(
|
entry_csv.append([entry['timestamp'], entry_words])
|
||||||
c if c in string.ascii_letters+"'" else ' '
|
|
||||||
for c in content.lower()
|
|
||||||
).split()
|
|
||||||
|
|
||||||
word_frequency.update(words)
|
|
||||||
|
|
||||||
entry_words = len(words)
|
|
||||||
daily_words += entry_words
|
|
||||||
|
|
||||||
entry_csv.append([timestamp, entry_words])
|
|
||||||
|
|
||||||
daily_macros = daily_protein + daily_fat + daily_carbs
|
daily_macros = daily_protein + daily_fat + daily_carbs
|
||||||
|
|
||||||
@@ -164,8 +104,8 @@ def write_csv(fname, csv):
|
|||||||
with open(fname, 'w') as fp:
|
with open(fname, 'w') as fp:
|
||||||
fp.write('\n'.join(','.join(str(x) for x in row) for row in csv))
|
fp.write('\n'.join(','.join(str(x) for x in row) for row in csv))
|
||||||
|
|
||||||
write_csv('total.csv', total_csv)
|
write_csv('data/total.csv', total_csv)
|
||||||
write_csv('daily.csv', daily_csv)
|
write_csv('data/daily.csv', daily_csv)
|
||||||
write_csv('entry.csv', entry_csv)
|
write_csv('data/entry.csv', entry_csv)
|
||||||
write_csv('words.csv', words_csv)
|
write_csv('data/words.csv', words_csv)
|
||||||
write_csv('diet.csv', diet_csv)
|
write_csv('data/diet.csv', diet_csv)
|
||||||
|
|||||||
21
common.py
21
common.py
@@ -4,6 +4,9 @@ from datetime import datetime
|
|||||||
def parse_timestamp(timestamp):
|
def parse_timestamp(timestamp):
|
||||||
return datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S')
|
return datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
def format_timestamp(timestamp):
|
||||||
|
return datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
def parse_foods_file():
|
def parse_foods_file():
|
||||||
path = Path.home() / 'projects' / 'open-journal' / 'foods'
|
path = Path.home() / 'projects' / 'open-journal' / 'foods'
|
||||||
text = path.read_text()
|
text = path.read_text()
|
||||||
@@ -79,4 +82,22 @@ def parse_foods_file():
|
|||||||
|
|
||||||
return foods, recipes
|
return foods, recipes
|
||||||
|
|
||||||
|
def evaluate_food_entry(foods, recipes, value, name):
|
||||||
|
if name in recipes:
|
||||||
|
food = recipes[name]
|
||||||
|
|
||||||
|
if value == 0.0:
|
||||||
|
value = food['TOTAL']
|
||||||
|
|
||||||
|
food = {k: v*(value/food['TOTAL']) for k,v in food.items()}
|
||||||
|
elif name in foods:
|
||||||
|
if value == 0.0:
|
||||||
|
value = 100
|
||||||
|
|
||||||
|
food = {k: v*(value/100.0) for k,v in foods[name].items()}
|
||||||
|
else:
|
||||||
|
breakpoint()
|
||||||
|
print(f'ERROR: Invalid diet entry: {content}')
|
||||||
|
|
||||||
|
return food
|
||||||
|
|
||||||
|
|||||||
14
foods
14
foods
@@ -1,4 +1,13 @@
|
|||||||
|
|
||||||
|
KauraPasta
|
||||||
|
Energy 359kcal
|
||||||
|
Fat 3.5g
|
||||||
|
SaturatedFat 0.7g
|
||||||
|
Carbs 65g
|
||||||
|
Sugar 2.9g
|
||||||
|
Fiber 6g
|
||||||
|
Protein 13g
|
||||||
|
|
||||||
Kaurakeksi
|
Kaurakeksi
|
||||||
Energy 461kcal
|
Energy 461kcal
|
||||||
Fat 20g
|
Fat 20g
|
||||||
@@ -892,3 +901,8 @@ SkimMilk 100g
|
|||||||
Margarine 20g
|
Margarine 20g
|
||||||
TOTAL 788
|
TOTAL 788
|
||||||
|
|
||||||
|
KauraPastaVeggies
|
||||||
|
Oil 40g
|
||||||
|
KauraPasta 500g
|
||||||
|
PeasCornPepper 450g
|
||||||
|
TOTAL 1720g
|
||||||
|
|||||||
26
search.py
26
search.py
@@ -1,24 +1,20 @@
|
|||||||
from pathlib import Path
|
|
||||||
from subprocess import run
|
from subprocess import run
|
||||||
import re
|
|
||||||
import sys
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
entry_re = re.compile(r'^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})', re.MULTILINE)
|
from common import format_timestamp
|
||||||
|
|
||||||
|
journal = json.load(open('journal.json'))
|
||||||
|
|
||||||
matches = []
|
matches = []
|
||||||
|
keyword = sys.argv[1].lower()
|
||||||
|
|
||||||
for fpath in sorted((Path.home() / 'workspace' / 'journal').glob('*.md')):
|
for day, obj in journal.items():
|
||||||
header, *tmp = entry_re.split(fpath.read_text())
|
for entry in obj['entries']:
|
||||||
entries = list(zip(tmp[::2], tmp[1::2]))
|
for block in entry['blocks']:
|
||||||
|
if isinstance(block, str):
|
||||||
for (timestamp, content) in sorted(entries, key=lambda x: x[0]):
|
if keyword in block.lower().split():
|
||||||
content = '\n'.join(
|
matches.append((format_timestamp(entry['timestamp']), block))
|
||||||
part.replace('\n', ' ')
|
|
||||||
for part in content.split('\n\n')
|
|
||||||
)
|
|
||||||
|
|
||||||
if sys.argv[1].lower() in content.lower().split():
|
|
||||||
matches.append((timestamp, content))
|
|
||||||
|
|
||||||
buf = ''
|
buf = ''
|
||||||
|
|
||||||
|
|||||||
40
summary.py
40
summary.py
@@ -1,49 +1,32 @@
|
|||||||
from pathlib import Path
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from collections import Counter
|
import json
|
||||||
from functools import reduce
|
|
||||||
import re
|
|
||||||
import string
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
do_yesterday = len(sys.argv) > 1
|
from common import parse_foods_file, format_timestamp
|
||||||
|
|
||||||
from common import parse_foods_file
|
|
||||||
|
|
||||||
foods, recipes = parse_foods_file()
|
foods, recipes = parse_foods_file()
|
||||||
|
|
||||||
entry_re = re.compile(r'^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) ', re.MULTILINE)
|
do_yesterday = len(sys.argv) > 1
|
||||||
diet_re = re.compile(r'@diet (\d+g) ([a-zA-Z]+)')
|
|
||||||
|
|
||||||
day_index = -2 if do_yesterday else -1
|
day_index = -2 if do_yesterday else -1
|
||||||
|
|
||||||
current_day = list(sorted((Path.home() / 'workspace' /
|
journal = json.load(open('journal.json'))
|
||||||
'journal').glob('*.md')))[day_index]
|
|
||||||
|
|
||||||
header, *tmp = entry_re.split(current_day.read_text())
|
current_day = list(journal)[day_index]
|
||||||
entries = list(zip(tmp[::2], tmp[1::2]))
|
|
||||||
|
|
||||||
daily_grams = 0.0
|
daily_grams = 0.0
|
||||||
daily_calories = 0.0
|
daily_calories = 0.0
|
||||||
daily_protein = 0.0
|
daily_protein = 0.0
|
||||||
|
|
||||||
for (timestamp, content) in sorted(entries, key=lambda x: x[0]):
|
for entry in journal[current_day]['entries']:
|
||||||
content = '\n'.join(
|
|
||||||
part.replace('\n', ' ')
|
|
||||||
for part in content.split('\n\n')
|
|
||||||
)
|
|
||||||
|
|
||||||
has_printed = False
|
has_printed = False
|
||||||
entry_calories = 0.0
|
entry_calories = 0.0
|
||||||
entry_protein = 0.0
|
entry_protein = 0.0
|
||||||
for diet in diet_re.finditer(content):
|
for diet in (b for b in entry['blocks'] if type(b) != str and b['type'] == 'diet'):
|
||||||
if not has_printed:
|
if not has_printed:
|
||||||
print(f'-- {timestamp}')
|
print(f'-- {format_timestamp(entry["timestamp"])}')
|
||||||
has_printed = True
|
has_printed = True
|
||||||
|
|
||||||
value, name = diet.groups()
|
value = diet['amount']
|
||||||
value = float(value.removesuffix('g'))
|
name = diet['food']
|
||||||
|
|
||||||
if name in recipes:
|
if name in recipes:
|
||||||
food = recipes[name]
|
food = recipes[name]
|
||||||
@@ -58,8 +41,7 @@ for (timestamp, content) in sorted(entries, key=lambda x: x[0]):
|
|||||||
|
|
||||||
food = {k: v*(value/100.0) for k,v in foods[name].items()}
|
food = {k: v*(value/100.0) for k,v in foods[name].items()}
|
||||||
else:
|
else:
|
||||||
breakpoint()
|
print(f'ERROR: Invalid diet entry: {diet}')
|
||||||
print(f'ERROR: Invalid diet entry: {content}')
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
protein = round(food.get('Protein', 0.0), 2)
|
protein = round(food.get('Protein', 0.0), 2)
|
||||||
|
|||||||
Reference in New Issue
Block a user