Skip to content

Instantly share code, notes, and snippets.

@brumar
Created November 30, 2016 21:25
Show Gist options
  • Select an option

  • Save brumar/d3583779c5d907fac42450ebbdf0f9d5 to your computer and use it in GitHub Desktop.

Select an option

Save brumar/d3583779c5d907fac42450ebbdf0f9d5 to your computer and use it in GitHub Desktop.
v1 of a cli used remember each day of my live
import os
import sys
from datetime import timedelta, date, datetime
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import ftplib
import argparse
import subprocess
image_extensions = [".jpg", ".png"]
week_reviews = {1:6, 2:12, 3:25, 4:1, 5:52, 6:104, 7:0} # means that at day 1 (monday), the whole Week-6 is reviewed
# Note : 52 and 104 are actually better for [power = 1; ideal_coeff = 2.2] than 50 and 100 (not only to make a year round !)
day_reviews = {1:[], 2:[-11,-3, -4], 3:[-11, -10], 4:[-3], 5:[-2, -3], 6:[], 7:[]} # means that at day 2 (tuesday), J-11, J-3 and J-4 are reviewed
general_day_reviews = [-1, -19] # at each day J-1 and J-19 are reviewed
power = 2 # used in the loss function
ideal_coeff = 2.2 # ideal multiplicative factor between intervalls
font_file_path = "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf"
ftp_adress = "complete this"
ftp_login = "complete this"
ftp_password = 'complete this'
def find_loci_image(index):
for ext in image_extensions:
s = os.path.join("loci", str(index) + ext)
if os.path.isfile(s):
return s
else:
return None
def white_transparent(img):
img = img.convert("RGBA")
datas = img.getdata()
newData = []
for item in datas:
if item[0] > 240 and item[1] > 240 and item[2] > 240 and (item[0]+item[1]+item[2])/3 > 245:
newData.append((item[0], item[1], item[2], 50))
else:
newData.append(item)
img.putdata(newData)
return img
def draw_with_border(x, y, text, font, draw, b=1):
draw.text((x-b, y-b), text, font=font, fill=(0,0,0))
draw.text((x+b, y-b), text, font=font, fill=(0,0,0))
draw.text((x-b, y+b), text, font=font, fill=(0,0,0))
draw.text((x+b, y+b), text, font=font, fill=(0,0,0))
# now draw the text over it
draw.text((x, y), text, font=font, fill=(255,255,255))
def create_day(filename_loci, object_index, number, output):
i1 = Image.open("objects/"+str(object_index)+".jpg")
i1.convert("RGBA")
i1 = white_transparent(i1)
new_im = Image.open(filename_loci)
new_im.convert("RGBA")
new_im.paste(i1, (10, 10), i1)
draw = ImageDraw.Draw(new_im)
# font = ImageFont.truetype(<font-file>, <font-size>)
font = ImageFont.truetype(font_file_path, 130)
# draw.text((x, y),"Sample Text",(r,g,b))
if number<10 :
str_number = "0" + str(number)
else:
str_number = str(number)
draw_with_border(310, 70, str_number, font, draw, b=4)
new_im.save("days/"+output)
def daterange(start_date, end_date):
for n in range(int ((end_date - start_date).days)):
yield start_date + timedelta(n)
def get_number_from_date(current_date):
""" Gives the number related to the current date
Pegs accross first month of trimester : 1 to 30, 31 replaced by 91
Second month : 31 to 60, 61 replaced by 92
Third month : 61 to 90, 91 replaced by 93
"""
month = int(current_date.strftime("%m"))
day = int(current_date.strftime("%d"))
trimester_month_index = ((month % 3) - 1)
if(day == 31):
return trimester_month_index + 91
else:
return trimester_month_index * 30 + day
def get_peg_index_from_date(current_date):
""" Gives the peg index related to the current date
Pegs are indexed by weeks from iso calendar. Few exceptions :
- no 52th week when january
- rebind 51, 52 and 53 to 101,102, 103 (adding 10 each year, so that next year it wil use 111, 112, 113 etc..)
so that weeks can be stacked up by bundle of 50
- start with numbers superior to 100 to learn a new system
"""
years = int(current_date.strftime("%Y")) - 2016
week = current_date.isocalendar()[1]
if(int(current_date.strftime("%m")==1 and week > 51)):
week = 1
if(week > 50):
return 100 + years*10 + (week - 50)
return 100 + week + years * 50
def update_on_ftp():
onlyfiles = [f for f in os.listdir("days") if os.path.isfile(os.path.join("days", f))]
session = ftplib.FTP(ftp_adress, ftp_login,ftp_password)
session.cwd("www/each_day")
missing_list = [f for f in onlyfiles if f not in session.nlst()]
for image in missing_list:
with open(os.path.join("days", image), 'rb') as file:
session.storbinary('STOR '+image, file)
print("file added : {}".format(image))
session.quit()
def create_empty_text_file_if_not_exist(date):
filename_date = date.strftime("%Y-%m-%d.txt")
content_filename_date = "text_content/" + filename_date
if not os.path.isfile(content_filename_date):
with open(content_filename_date, 'a'):
print("write")
os.utime(content_filename_date, None)
return 1
return 0
def create_days_from_date(current_d):
index = 0
loci_added = 0
text_added = 0
while True:
index += 1
filename_date = current_d.strftime("%Y-%m-%d.jpg")
if os.path.isfile("days/"+filename_date):
current_d += timedelta(1)
continue
filename_loci = find_loci_image(index)
if not filename_loci:
print("end of the list of " + str(index-1) +" loci")
print(str(loci_added)+" days have been added")
print(str(text_added)+" blank logs have been added")
break
object_index = get_peg_index_from_date(current_d)
number = get_number_from_date(current_d)
create_day(filename_loci, object_index, number, output=filename_date)
text_added += create_empty_text_file_if_not_exist(current_d)
print("filename date: {}".format(filename_date))
print("object index: {}".format(object_index))
print("number: {}".format(number))
current_d += timedelta(1)
loci_added += 1
def review_S_minus_X(day_index, X):
first_day = X*7 + day_index
last_day = (X-1)*7 + day_index
# print([-i for i in range(last_day, first_day)])
return [-i for i in range(last_day, first_day)]
def repeat_weeks(day_index):
week_to_review = week_reviews[day_index]
return review_S_minus_X(day_index, week_to_review)
def repeat_for_day(day_index):
"""Each day has a special revision task in order to keep
intervals expanding as smoothly as possible.
Week reviews are not included
"""
return day_reviews[day_index]
def reviews(index_day):
l = general_day_reviews[:]
# print(index_day)
l.extend(repeat_for_day(index_day))
# print(l)
l.extend(repeat_weeks(index_day))
# print(l)
return sorted(l)
def print_review(date_now):
print("review for: ", date_now.strftime("%Y-%m-%d"))
delta_reviews = reviews(date_now.isocalendar()[2])
dates = []
for delta in delta_reviews:
date_to_review = date_now + timedelta(delta)
strftime = date_to_review.strftime("%Y-%m-%d")
onlyfiles = [f for f in os.listdir("days") if os.path.isfile(os.path.join("days", f))]
if(strftime+".jpg" in onlyfiles):
dates.append(strftime)
print(strftime)
#o = raw_input("open ? (y/n)")
#if o == "y":
# for date in dates:
# filepath = os.path.join("days", date+".jpg")
# print(filepath)
# subprocess.Popen(["xdg-open", filepath])
#subprocess.call(["xdg-open", file])
def benchmark(delta):
start = date(2016, 11, 6)
week_day = [[0], [0], [0], [0], [0], [0], [0]]
error_sum = 0
for i in xrange(delta):
start = start + timedelta(1)
delta_reviews = reviews(start.isocalendar()[2])
for d in delta_reviews:
index_day_to_review = d + i
if index_day_to_review > -1 and d + i < 7:
week_day[index_day_to_review].append(d*-1)
for wd in xrange(0, 7):
week_day_i = sorted(list(set(week_day[wd])))
intervals = [week_day_i[i+1] - week_day_i[i] for i in range(0, len(week_day_i)-1)]
coeffs = [intervals[i+1] / float(intervals[i]) for i in range(0, len(intervals)-1)]
print("reviews for day {} :".format(wd+1))
print(" - reviews :" + str(week_day_i))
print(" - intervals :" + str(intervals))
print(" - coeffs :" + str(coeffs))
for c in coeffs:
error = c - ideal_coeff
if error > 0:
error_sum += pow(error + 1, power) - 1 # ensure that if error is 0, the term added is 0
else:
error_sum += abs(error)
print("total error for this setting is " + str(error_sum))
return error_sum
if __name__ == "__main__":
starting_date = date(2016, 11, 2)
parser = argparse.ArgumentParser(description='CLI to review each day')
parser.add_argument('--create', help='create the day images', action="store_true")
parser.add_argument('--review', help='today review (or what was planned the xth previous day if argument is supplied)', default=0, nargs='?', const=-1, type=int)
parser.add_argument('--ftp', help='send to ftp', action="store_true")
parser.add_argument('--benchmark', help='benchmark', action="store_true")
args = parser.parse_args()
if args.create:
create_days_from_date(starting_date)
if args.ftp:
update_on_ftp()
if args.review:
if args.review == -1:
d = 0
else:
d = args.review
print_review(datetime.now()-timedelta(d))
if args.benchmark:
benchmark(delta=1500)
if len(sys.argv)==1:
parser.print_help()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment