23 def wordcount_at_this_sha():
24 result = subprocess.run("wc -w content/drafts/blanchards-dangerous-idea-and-the-plight-of-the-lucid-crossdreamer.md content/drafts/a-hill-of-validity-in-defense-of-meaning.md content/drafts/if-clarity-seems-like-death-to-them.md content/drafts/agreeing-with-stalin-in-ways-that-exhibit-generally-rationalist-principles.md content/drafts/standing-under-the-same-sky.md".split(), stdout=subprocess.PIPE)
25 wc_lines = result.stdout.decode('utf8').split('\n')
26 total_line = wc_lines[-2] # last line is empty
27 return int(total_line.split()[0])
29 def date_at_this_sha():
30 result = subprocess.run("git show HEAD".split(), stdout=subprocess.PIPE)
31 show_lines = result.stdout.decode('utf8').split('\n')
32 dateline = show_lines[2]
33 match_groups = re.search("(?P<month>\w{3}) (?P<day>\d{1,2}) \d{2}:\d{2}:\d{2} (?P<year>\d{4})", dateline).groupdict()
34 return datetime.date(int(match_groups['year']), MONTHS[match_groups['month']], int(match_groups['day']))
41 subprocess.run(["git", "checkout", "HEAD~1"])
42 wordcount = wordcount_at_this_sha()
43 date = date_at_this_sha()
44 if date < datetime.date(2022, 4, 20):
46 wordcounts.append((date, wordcount))
47 # don't leave the head detached
48 subprocess.run(["git", "checkout", "master"])
49 return sorted(wordcounts)
51 def normalize_dates(wordcounts):
53 for i in range(len(wordcounts)-1):
54 date, wordcount = wordcounts[i]
55 next_date, next_wordcount = wordcounts[i+1]
56 gap = next_date - date
57 if gap >= datetime.timedelta(1):
58 eod_wordcounts.append((date, wordcount))
59 for i in range(gap.days-1):
60 eod_wordcounts.append((date + datetime.timedelta(i+1), wordcount))
63 def write_csv(wordcounts):
64 with open("memoir_wordcounts.csv", 'w') as f:
65 writer = csv.writer(f)
66 for date, wordcount in wordcounts:
67 writer.writerow([date.strftime("%m/%d/%Y"), wordcount])
70 if __name__ in "__main__":
71 wordcounts = normalize_dates(look_back())