initial
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
**/*.csv
|
||||
186
analyze.py
Normal file
186
analyze.py
Normal file
@@ -0,0 +1,186 @@
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
from collections import Counter
|
||||
from functools import reduce
|
||||
import re
|
||||
import string
|
||||
|
||||
def parse_foods_file():
|
||||
path = Path.home() / 'projects' / 'open-journal' / 'foods'
|
||||
text = path.read_text()
|
||||
foods, recipes = text.split('---')
|
||||
|
||||
def parse_macro(macro):
|
||||
if macro == '...':
|
||||
return ('INVALID', 0.0)
|
||||
|
||||
name, value = macro.split()
|
||||
value = float(value.removesuffix('g').removesuffix('kcal'))
|
||||
return (name, value)
|
||||
|
||||
foods = {
|
||||
macros[0]: dict(parse_macro(macro) for macro in macros[1:])
|
||||
for macros in [food.split('\n') for food in foods.strip().split('\n\n')]
|
||||
}
|
||||
|
||||
def combine_values(fst, snd):
|
||||
result = fst.copy()
|
||||
for k,v in snd.items():
|
||||
if k in fst:
|
||||
result[k] += v
|
||||
else:
|
||||
result[k] = v
|
||||
return result
|
||||
|
||||
def evaluate_ingredients(ingredients):
|
||||
result = {}
|
||||
|
||||
total_weight = 0.0
|
||||
for ingredient in ingredients:
|
||||
k,v = parse_macro(ingredient)
|
||||
if k == 'TOTAL':
|
||||
result[k] = v
|
||||
break
|
||||
else:
|
||||
total_weight += v
|
||||
|
||||
|
||||
food = foods[k]
|
||||
|
||||
for kk,vv in food.items():
|
||||
if kk not in result:
|
||||
result[kk] = 0.0
|
||||
|
||||
result[kk] += vv * (v/100.0)
|
||||
|
||||
if 'TOTAL' not in result:
|
||||
result['TOTAL'] = total_weight
|
||||
|
||||
return result
|
||||
|
||||
recipes = {
|
||||
ingredients[0]: evaluate_ingredients(ingredients[1:])
|
||||
for ingredients in [
|
||||
recipe.split('\n') for recipe in recipes.strip().split('\n\n')
|
||||
]
|
||||
}
|
||||
|
||||
def get_calories_from_macros(mm):
|
||||
calories = 0.0
|
||||
for k,v in mm.items():
|
||||
calories += v * {
|
||||
'Carbs': 4,
|
||||
'Fat': 8,
|
||||
'Protein': 4
|
||||
}.get(k, 0.0)
|
||||
return calories
|
||||
|
||||
#for k,v in foods.items():
|
||||
# print(round(v.get('Energy') - get_calories_from_macros(v)), k)
|
||||
|
||||
return foods, recipes
|
||||
|
||||
foods, recipes = parse_foods_file()
|
||||
|
||||
|
||||
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_words = 0
|
||||
word_frequency = Counter()
|
||||
|
||||
total_csv = [['day', 'entries', 'words']]
|
||||
daily_csv = [['day', 'entries', 'words', 'calories']]
|
||||
entry_csv = [['timestamp', 'words']]
|
||||
words_csv = [['word', 'count']]
|
||||
|
||||
diet_csv = [[
|
||||
'timestamp', 'name', 'grams', 'calories', 'carbs', 'fat', 'protein',
|
||||
'saturated_fat', 'sugar', 'fiber'
|
||||
]]
|
||||
|
||||
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_calories = 0.0
|
||||
|
||||
for (timestamp, content) in sorted(entries, key=lambda x: x[0]):
|
||||
timestamp = int(datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S').timestamp())
|
||||
|
||||
content = '\n'.join(
|
||||
part.replace('\n', ' ')
|
||||
for part in content.split('\n\n')
|
||||
)
|
||||
|
||||
for diet in diet_re.finditer(content):
|
||||
value, name = diet.groups()
|
||||
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
|
||||
|
||||
|
||||
diet_csv.append((
|
||||
timestamp,
|
||||
name,
|
||||
value,
|
||||
round(food.get('Energy', 0.0), 2),
|
||||
round(food.get('Carbs', 0.0), 2),
|
||||
round(food.get('Fat', 0.0), 2),
|
||||
round(food.get('Protein', 0.0), 2),
|
||||
round(food.get('SaturatedFat', 0.0), 2),
|
||||
round(food.get('Sugar', 0.0), 2),
|
||||
round(food.get('Fiber', 0.0), 2),
|
||||
))
|
||||
|
||||
daily_calories += food.get('Energy', 0.0)
|
||||
|
||||
words = ''.join(
|
||||
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_csv.append([day, daily_entries, daily_words, daily_calories])
|
||||
|
||||
total_entries += daily_entries
|
||||
total_words += daily_words
|
||||
|
||||
total_csv.append([day, total_entries, total_words])
|
||||
|
||||
words_csv += word_frequency.most_common()
|
||||
|
||||
def write_csv(fname, csv):
|
||||
with open(fname, 'w') as fp:
|
||||
fp.write('\n'.join(','.join(str(x) for x in row) for row in csv))
|
||||
|
||||
write_csv('total.csv', total_csv)
|
||||
write_csv('daily.csv', daily_csv)
|
||||
write_csv('entry.csv', entry_csv)
|
||||
write_csv('words.csv', words_csv)
|
||||
write_csv('diet.csv', diet_csv)
|
||||
5
backup-script.sh
Normal file
5
backup-script.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
apack $1 *.md
|
||||
rclone copy $1 gdrive:/journal-backup/
|
||||
rclone copy $1 prodesk:/home/olari/journal-backup/
|
||||
rm $1
|
||||
432
foods
Normal file
432
foods
Normal file
@@ -0,0 +1,432 @@
|
||||
|
||||
RainbowNoodles
|
||||
Energy 451kcal
|
||||
Fat 18g
|
||||
SaturatedFat 8.6g
|
||||
Carbs 63g
|
||||
Sugar 1.7g
|
||||
Protein 11g
|
||||
Salt 4.6g
|
||||
|
||||
Banana
|
||||
Energy 89kcal
|
||||
Carbs 22.84g
|
||||
Sugar 12.23g
|
||||
Fiber 2.6g
|
||||
Fat 0.33g
|
||||
Protein 1.09g
|
||||
|
||||
Oil
|
||||
Energy 828kcal
|
||||
Fat 92g
|
||||
SaturatedFat 7g
|
||||
MonosaturatedFat 57g
|
||||
PolysaturatedFat 28g
|
||||
|
||||
Egg
|
||||
Energy 155kcal
|
||||
Carbs 1.12g
|
||||
Fat 10.6g
|
||||
Protein 12.6g
|
||||
|
||||
Milk
|
||||
Energy 64kcal
|
||||
Fat 3.5g
|
||||
SaturatedFat 2.3g
|
||||
Protein 3.2g
|
||||
Salt 0.1g
|
||||
|
||||
BellPepper
|
||||
Energy 31kcal
|
||||
Protein 1g
|
||||
Carbs 6g
|
||||
Sugar 4.2g
|
||||
Fiber 2.1g
|
||||
Fat 0.3g
|
||||
|
||||
Flour
|
||||
Energy 349kcal
|
||||
Fat 1.4g
|
||||
SaturatedFat 0.3g
|
||||
Carbs 71.5g
|
||||
Sugar 1.7g
|
||||
Fiber 2.4g
|
||||
Protein 11.4g
|
||||
Salt 0.01g
|
||||
|
||||
Salt
|
||||
Energy 0kcal
|
||||
Salt 100g
|
||||
|
||||
Cheese
|
||||
Energy 329kcal
|
||||
Fat 24g
|
||||
SaturatedFat 14g
|
||||
Protein 27g
|
||||
Salt 1.5g
|
||||
|
||||
Potato
|
||||
Energy 68kcal
|
||||
Fat 0.2g
|
||||
Carbs 13.3g
|
||||
Protein 1.6g
|
||||
Fiber 0.8g
|
||||
|
||||
SweetPotato
|
||||
Energy 86kcal
|
||||
Carbs 20g
|
||||
Fiber 3g
|
||||
Sugar 4.2g
|
||||
Protein 1.6g
|
||||
|
||||
Salad
|
||||
Energy 10kcal
|
||||
Fat 0.2g
|
||||
SaturatedFat 0g
|
||||
Carbs 1g
|
||||
Sugar 0.5g
|
||||
Protein 1.1g
|
||||
|
||||
SaladDressing
|
||||
Energy 259kcal
|
||||
Fat 22.3g
|
||||
SaturatedFat 1.5g
|
||||
Carbs 14g
|
||||
Sugar 10.8g
|
||||
Protein 0.4g
|
||||
Salt 0.99g
|
||||
|
||||
PeasCornPepper
|
||||
Energy 85kcal
|
||||
Fat 0.7g
|
||||
SaturatedFat 0.2g
|
||||
Carbs 12g
|
||||
Sugar 2.4g
|
||||
Fiber 5.5g
|
||||
Protein 4.9g
|
||||
Salt 0.07g
|
||||
|
||||
Muesli
|
||||
Energy 391kcal
|
||||
Fat 10.9g
|
||||
SaturatedFat 3.9g
|
||||
Carbs 61.9g
|
||||
Sugar 26.7g
|
||||
Fiber 6g
|
||||
Protein 8.4g
|
||||
Salt 0.08g
|
||||
|
||||
Margarine
|
||||
Energy 630kcal
|
||||
Fat 70g
|
||||
SaturatedFat 20g
|
||||
UnsaturatedFat 35g
|
||||
|
||||
PickleSlices
|
||||
Energy 54kcal
|
||||
Sugar 12.1g
|
||||
Salt 1g
|
||||
|
||||
Ketchup
|
||||
Energy 102kcal
|
||||
Carbs 23.2g
|
||||
Sugar 22.8g
|
||||
Protein 1.2g
|
||||
Salt 1.8g
|
||||
|
||||
WhiteBread
|
||||
Energy 253kcal
|
||||
Fat 2.5g
|
||||
SaturatedFat 0.3g
|
||||
Carbs 45g
|
||||
Sugar 1.1g
|
||||
Fiber 6.1g
|
||||
Protein 9.4g
|
||||
Salt 1.1g
|
||||
|
||||
DarkBread
|
||||
Energy 242kcal
|
||||
Fat 1.3g
|
||||
SaturatedFat 0.2g
|
||||
Carbs 43.6g
|
||||
Sugar 1.4g
|
||||
Fiber 11.7g
|
||||
Protein 8.2g
|
||||
Salt 1.1g
|
||||
|
||||
KauraTyynyt
|
||||
Energy 254kcal
|
||||
Fat 4.1g
|
||||
SaturatedFat 0.5g
|
||||
Carbs 39g
|
||||
Sugar 0.8g
|
||||
Fiber 6.6g
|
||||
Protein 12g
|
||||
Salt 1.1g
|
||||
|
||||
BiscuitRings
|
||||
Energy 541kcal
|
||||
Fat 30.1g
|
||||
SaturatedFat 14.8g
|
||||
Carbs 61.8g
|
||||
Sugar 23.1g
|
||||
Protein 4.6g
|
||||
Salt 0.48g
|
||||
|
||||
SobaChili
|
||||
Energy 218kcal
|
||||
Fat 9.3g
|
||||
SaturatedFat 4.4g
|
||||
Carbs 27.4g
|
||||
Sugar 6g
|
||||
Protein 4.9g
|
||||
Salt 2.3g
|
||||
|
||||
CocaCola
|
||||
Energy 42kcal
|
||||
Carbs 10.6g
|
||||
Sugar 10.6g
|
||||
|
||||
Pasta
|
||||
Energy 348kcal
|
||||
Fat 1.7g
|
||||
SaturatedFat 0.4g
|
||||
Carbs 67g
|
||||
Sugar 2.5g
|
||||
Fiber 4g
|
||||
Protein 13g
|
||||
|
||||
SaskiaPeach
|
||||
Energy 16kcal
|
||||
Sugar 4g
|
||||
|
||||
GelatelliVeganIceCream
|
||||
Energy 342kcal
|
||||
Fat 21.3g
|
||||
SaturatedFat 16g
|
||||
Carbs 34.3g
|
||||
Sugar 24.2g
|
||||
Protein 2.3g
|
||||
|
||||
BrownRice
|
||||
Energy 371kcal
|
||||
Fat 2g
|
||||
SaturatedFat 0.5g
|
||||
Carbs 77g
|
||||
Fiber 8.7g
|
||||
Protein 7.1g
|
||||
|
||||
SojaRouha
|
||||
Energy 77kcal
|
||||
Carbs 6.2g
|
||||
Sugar 3.15g
|
||||
Protein 12.21g
|
||||
Salt 1.34g
|
||||
|
||||
MonsterEnergy
|
||||
Energy 47kcal
|
||||
Sugar 11g
|
||||
|
||||
MousseCherry
|
||||
Energy 535kcal
|
||||
Fat 36.4g
|
||||
SaturatedFat 21.2g
|
||||
Carbs 41.4g
|
||||
Sugar 31.4g
|
||||
Protein 6.5g
|
||||
|
||||
FoodCream
|
||||
Energy 161kcal
|
||||
Fat 15g
|
||||
SaturatedFat 10g
|
||||
Carbs 4.7g
|
||||
Sugar 3.7g
|
||||
|
||||
Honey
|
||||
Energy 64kcal
|
||||
Carbs 17g
|
||||
Sugar 17g
|
||||
|
||||
Coffee
|
||||
Energy 0kcal
|
||||
|
||||
Oatmeal
|
||||
Energy 68kcal
|
||||
Fat 1.4g
|
||||
Carbs 12g
|
||||
Sugar 0.5g
|
||||
Fiber 1.7g
|
||||
Protein 2.4g
|
||||
|
||||
VahvlitortTallinn
|
||||
Energy 505kcal
|
||||
Fat 51g
|
||||
Carbs 40g
|
||||
Sugar 25g
|
||||
Protein 6g
|
||||
|
||||
TaffelJuustoSnaks
|
||||
Energy 550kcal
|
||||
Fat 33g
|
||||
SaturatedFat 6.2g
|
||||
Carbs 51g
|
||||
Sugar 3.6g
|
||||
Protein 10g
|
||||
Salt 1.8g
|
||||
|
||||
FakeChicken
|
||||
Energy 142kcal
|
||||
Fat 5g
|
||||
SaturatedFat 0.5g
|
||||
Carbs 11.3g
|
||||
Sugar 1.57g
|
||||
Protein 13.14g
|
||||
Salt 0.39g
|
||||
|
||||
SourCream
|
||||
Energy 139kcal
|
||||
Fat 12g
|
||||
SaturatedFat 6.7g
|
||||
Carbs 4g
|
||||
Sugar 4g
|
||||
Protein 2.8g
|
||||
Salt 0.1g
|
||||
|
||||
WhiteBeansTomatoSauce
|
||||
Energy 105kcal
|
||||
Protein 4g
|
||||
Carbs 18g
|
||||
Sugar 2g
|
||||
|
||||
CherryTomatoes
|
||||
Energy 18kcal
|
||||
Carbs 3.92g
|
||||
Sugar 2.62g
|
||||
Fiber 1.2g
|
||||
Protein 0.88g
|
||||
Fat 0.2g
|
||||
|
||||
BerryMustikaVaarika
|
||||
Energy 85kcal
|
||||
Carbs 13g
|
||||
Sugar 7.2g
|
||||
Fiber 4.7g
|
||||
Protein 0.95g
|
||||
|
||||
VanilliIceCream
|
||||
Energy 160kcal
|
||||
Fat 6.3g
|
||||
SaturatedFat 4.1g
|
||||
Carbs 22.5g
|
||||
Sugar 19.9g
|
||||
Protein 3.2g
|
||||
Salt 0.12g
|
||||
|
||||
Cocoa
|
||||
Energy 373kcal
|
||||
Fat 2.9g
|
||||
SaturatedFat 1.5g
|
||||
Carbs 78.6g
|
||||
Sugar 76.6g
|
||||
Protein 4.8g
|
||||
Salt 0.31g
|
||||
|
||||
Sugar
|
||||
Energy 400kcal
|
||||
Carbs 100g
|
||||
Sugar 100g
|
||||
|
||||
KeishaCandy
|
||||
Energy 553kcal
|
||||
Fat 35g
|
||||
SaturatedFat 18g
|
||||
Carbs 47g
|
||||
Sugar 45g
|
||||
Protein 8.1g
|
||||
Salt 0.13g
|
||||
|
||||
ProteinSpaghetti
|
||||
Energy 350kcal
|
||||
Fat 2.5g
|
||||
SaturatedFat 0.6g
|
||||
Carbs 66g
|
||||
Sugar 3.7g
|
||||
Fiber 7.5g
|
||||
Protein 12g
|
||||
|
||||
PastaSauce
|
||||
Energy 61kcal
|
||||
Fat 1.9g
|
||||
SaturatedFat 0.2g
|
||||
Carbs 9.2g
|
||||
Sugar 5.7g
|
||||
Protein 1.3g
|
||||
Salt 1.27g
|
||||
|
||||
---
|
||||
|
||||
Omlette
|
||||
BellPepper 50g
|
||||
Cheese 25g
|
||||
Egg 180g
|
||||
Flour 25g
|
||||
Milk 80g
|
||||
Oil 25g
|
||||
Salt 2g
|
||||
|
||||
MashedPotato
|
||||
Margarine 40g
|
||||
Milk 180g
|
||||
Potato 1000g
|
||||
TOTAL 1300g
|
||||
|
||||
Blov
|
||||
BrownRice 600g
|
||||
Ketchup 250g
|
||||
Oil 50g
|
||||
SojaRouha 300g
|
||||
PeasCornPepper 225g
|
||||
TOTAL 2460g
|
||||
|
||||
RoastedVeggies
|
||||
Oil 100g
|
||||
Potato 1000g
|
||||
SweetPotato 450g
|
||||
|
||||
MilkSoup
|
||||
Margarine 30g
|
||||
Milk 500g
|
||||
Oil 25g
|
||||
Pasta 350g
|
||||
Sugar 10g
|
||||
TOTAL 1315
|
||||
|
||||
Pancake
|
||||
Egg 120g
|
||||
Milk 600g
|
||||
Oil 50g
|
||||
Sugar 12g
|
||||
Flour 300g
|
||||
|
||||
CreamPotatoes
|
||||
Cheese 170g
|
||||
FoodCream 450g
|
||||
Oil 50g
|
||||
Potato 1500g
|
||||
|
||||
FakeChickenVeggies
|
||||
FakeChicken 250g
|
||||
Oil 50g
|
||||
PeasCornPepper 225g
|
||||
|
||||
OmletteWithoutMilk
|
||||
Cheese 25g
|
||||
Egg 180g
|
||||
Flour 25g
|
||||
Milk 80g
|
||||
Oil 25g
|
||||
|
||||
ProteinSpaghettiBolognese
|
||||
ProteinSpaghetti 500g
|
||||
PastaSauce 500g
|
||||
TOTAL 1640g
|
||||
42
open-journal.py
Normal file
42
open-journal.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from subprocess import run, Popen, DEVNULL
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
import random
|
||||
import sys
|
||||
|
||||
current_date = datetime.now().strftime('%Y-%m-%d')
|
||||
current_time = datetime.now().strftime('%H:%M:%S')
|
||||
|
||||
journal_path = Path.home() / 'workspace' / 'journal'
|
||||
|
||||
target_page = journal_path / f'{current_date}.md'
|
||||
|
||||
script_path = Path(__file__).parent
|
||||
|
||||
habits = '\n'.join([f'[-] {x}'
|
||||
for x in (script_path / 'habits').read_text().strip().split('\n')])
|
||||
|
||||
words = (script_path / 'godword').read_text().strip().split('\n')
|
||||
godword = '\n'.join(' '.join(random.choice(words)
|
||||
for a in range(10)) for _ in range(2))
|
||||
|
||||
if not target_page.exists():
|
||||
Popen(
|
||||
['bash', str(script_path / 'backup-script.sh'), current_date+'.zip'],
|
||||
cwd=str(journal_path), stdout=DEVNULL, stderr=DEVNULL
|
||||
)
|
||||
|
||||
target_page.write_text(f'''\
|
||||
# {target_page.stem}
|
||||
|
||||
Godword:
|
||||
{godword}
|
||||
|
||||
Habits:
|
||||
{habits}
|
||||
''')
|
||||
|
||||
with open(target_page, 'a') as fp:
|
||||
fp.write(f'\n{current_date} {current_time} ')
|
||||
|
||||
run(['nvim', str(target_page), '+'])
|
||||
Reference in New Issue
Block a user