Created
November 30, 2016 21:25
-
-
Save brumar/d3583779c5d907fac42450ebbdf0f9d5 to your computer and use it in GitHub Desktop.
v1 of a cli used remember each day of my live
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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