-2
from tkinter import *
from datetime import datetime, timedelta 
import pickle
from tkinter import messagebox

filename = "file.pk" #filename data stored as dic = {time:[name,item]}

root = Tk()

t = IntVar()
i = StringVar()
n = StringVar()


def Notification_On_Completing(n, i, t):
    return messagebox.showinfo("Completed", "Name:- {}, Item:-{}, in Days:-{}".format(n, i, t)) 


def Check_If_Time_Is_Over():   #my actual problem is in this function 

    with open(filename, "rb") as f: 
        dic = pickle.load(f)

    now = datetime.now()

    for i, j in dic: #trying to loop and check if the time == now() 
            if i == now: 
                Notification_On_Completing(j[0], j[1], i) #if its true return the key which is equal with its value

            elif i != now: #if now time i am tryinng to show how much time left
                print(i - now, "Time has left for name:-{}, item:-{}".format(j[0],j[1]))
            else:
                root.after(10000, Check_If_Time_Is_Over)

def SaveTheDaysToNotify():

    now = datetime.now()
    time = t.get()  # days to wait beforer notifying
    item = i.get()  #item name    
    name = i.get()  #name 

    end = now + timedelta(days=time)  #adding today with the number of days to notify

    with open(filename.pk, "rb") as f: # avoiding the overide of the files
        dic = pickle.load(f)

    dic= {end:[name, item]}  # saving a days to notify as dic which will also show the name , and item
    with open("file.pk", "wb") as f: #keeping record of the time time to notify
        pickle.dump(dic, f)
    Check_If_Time_Is_Over()


#Gui starts from here

time1 = Entry(root,textvariable=t).pack()  #taking entry as of time, name and item
name1 = Entry(root,textvariable=n).pack()

item1 = Entry(root, textvariable=i).pack()

ss = Button(root,text="done",command=SaveTheDaysToNotify).pack() #adding to the pickle database with format as dictionary as dic ={time:[name, item]}

root.mainloop() Check_If_Time_Is_Over()

I am trying to make a program which will take a entry as Time, item, name.Time will be taken as days to show notification after.For example the program should show the notification after x days and continously checking the if the x days has come even if the program would be closed and reopened for certain times in days or hours interval.

1 Answers1

0

You can store the date of the input as well as the number inside a file. You can use datetime.timedelta to add days to your time.

Every time your program is run you check if this special file is present, read the date and the number, check if date+number_days is today or before today and create your notification.

If your program is not startet, it wont show anything. If your program is not closed in between it wont show anything - the latter case could be accomplished with some timers and checking periodically inside TKs main loop (remeber hour, if changed, check file again or smth...)

Example:

import os

from datetime import datetime , timedelta

fn = "myfile.txt"
date = None
days = None

def delDateFile():
    """Remove date file after showing notification, so next time user will
    be asked to input days again."""
    os.remove(fn)

def writeDate(d:int):
    """Adds d days to now(), writes it to file and returns the date."""
    date = datetime.now()  + timedelta(days = d)
    with open(fn,"w") as f: # overwriting existing file
        f.write(stringFromDate(date ))
    return date.date()

def dateFromString(s):
    """Parses a string into a date. Format: '%Y-%m-%d'"""
    try:
         return datetime.strptime(s,'%Y-%m-%d').date()
    except ValueError:
        print("Malformed date")
        return writeDate(-1)        

def stringFromDate(d):
    """Makes a string from a date. Format: '%Y-%m-%d'"""
    return datetime.strftime(datetime.now(),'%Y-%m-%d')


def needToShowNotification():
    def checkIfFileExistsAndExtractDate():
        """Reads a date from file, returns date from file or None if no file exists."""
        if os.path.exists(fn):
            with open(fn,"r") as f:
                date = dateFromString(f.readline())
            return date 
        return None

    def askForDaysAndWriteFile():
        """Asks for days and writes a file with the new date. Malformed input produces date of yesterday"""
        try:
            days = int(input("Days? "))
        except (ValueError, EOFError): # malformed input: empty or no number
            days = -1

        return writeDate(days) 


    # prefer date from file, else ask and write file
    date = checkIfFileExistsAndExtractDate() or askForDaysAndWriteFile()

    return date < datetime.now().date()


def Notif():
    print("------------------")
    print("-- NOTIFICATION --")
    print("------------------")
    delDateFile()

if needToShowNotification():
    Notif()
else:
    print("Go ahead, no need to notify")

Run it with a negative days input to see the notification (or delete the created file)

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • I want it to be check every second if its the day i wanted .....how would i do that and how can i show real timer of countdown from start to end day – HEalik Tamu Mar 29 '18 at 12:21
  • @HEalikTamu Why would you need to check if every second? days only swith every 24*60*60 seconds ... If you just want to create a "clock" search it - and find f.e.: [how-to-create-a-timer-using-tkinter](https://stackoverflow.com/questions/2400262/how-to-create-a-timer-using-tkinter) – Patrick Artner Mar 29 '18 at 19:34
  • no if the time != now then i want it to show how much time is left in real time with tkinter ....plz i need some help – HEalik Tamu Mar 30 '18 at 05:06
  • i want is if the time != now then it should print the remaining time in tkinter plz help – HEalik Tamu Mar 30 '18 at 05:12
  • @HEalikTamu Look to the answers of [how-to-create-a-timer](https://stackoverflow.com/questions/2400262/how-to-create-a-timer-using-tkinter) which I linked above as well. They all create clocks using Tk and a timer - modify those solutions to not display the current time but the deltatime between datetime.now().time() and your target days time 0:0:0 (or whatever time you want). They also provide you with examples how to use `.after()` that shows how to activate the timer. Figure it out yourself, youre learning more that way then when I code it. – Patrick Artner Mar 30 '18 at 05:20