Reputation: 109
I am very new to Python, but the project I am working on confused me. In the project, I give multiple choices for uses to choose, one of the choices has a reminder function. So in the reminder function, the user can set reminder, and the function will match the reminder to current time every 15 seconds until they match and print a statement.
This is the code for reminder.
import time
def setReminder(number):
reminderList = []
for i in range(number):
reminderL = []
mon = input('enter the month(1-12):')
day = input('enter the date(1-31):')
hour = input('enter the hour(0-23):')
minute = input('enter the minute(0-59):')
print()
if ((int(mon)<1 or int(mon)>12)
or (int(day)<1 or int(day)>31)
or (int(hour)<0 or int(hour)>23)
or (int(minute)<0 or int(minute)>59)):
print('invalid date and time, please set again!')
mon = input('enter the month(1-12):')
day = input('enter the date(1-31):')
hour = input('enter the hour(0-23):')
minute = input('enter the minute(0-59):')
reminderL.extend((mon, day, hour, minute))
reminder = ''
for element in reminderL:
if int(element)<10:
element = '0' + element
reminder = reminder + element + ' '
reminderList.append(reminder)
return reminderList
def main():
num = int(input('enter the numbers of reminder you want to set(1-9):'))
if num not in range(1,10):
print('invalid input, try again!')
num = int(input('enter the numbers of reminder you want to set(0-9):'))
List = setReminder(num)
print(List)
for i in range(num):
tim = time.strftime('%m %d %H %M ')
while tim not in List:
time.sleep(15)
tim = time.strftime('%m %d %H %M ')
print('Hello, it is time to take medicine!')
main()
However, if the user set the reminder time to very late, for example next day, then this function will run until next day. Hence I want my body script to run while this reminder function is running.
This is generally how my body script is like(it is in a different script with the reminder one):
menu()
option = int(input('Your choice?'))
while (option != 4):
if option not in (1, 2, 3, 4):
print('Invalid input! Please select again!')
option = int(input('Your choice?'))
else:
if option == 1:
print()
elif option == 2:
feedback(gender, dat)
elif option == 3:
print()
print()
print('Anything else?')
menu()
option = int(input('Your choice?'))
So option 3 is the reminder, but while reminder function is try to match the time, I want the user to be able to use the other choices. The only way I think can work is to call the function and run it on another shell page. Could you give me any advice on how to do so?
Upvotes: 1
Views: 149
Reputation:
The tool you need is threading
. Suppose you have two separate script files: reminder.py
and program.py
. Then you have to delete or comment out line main()
in reminder
and import reminder
and threading
into program
. Next is to modify program
:
elif option == 3:
rem_thread = threading.Thread(
target=reminder.main)
rem_thread.start()
This is very basic example of how to use threads in Python. However, this addition to the code cannot solve your problem because of two reasons: (1) interference between input()
calls in different threads; (2) blocking by input()
. To solve the first problem you should pause main thread while user enters time parts. To solve the second problem you should start one more thread.
Here is the code that kinda works (Win10 / command prompt). There is a whole bunch of design issues to be addressed to make the code more or less usable. I tested it with 1 remainder because every remainder needs separate thread. Interference between input()
and print()
still present because several threads share the same console. This issue can be solved with processes instead of threads or with GUI. Of course, GUI is preferable.
import queue
import threading
import time
def setReminder(number):
reminderList = []
for i in range(number):
reminderL = []
mon = input('enter the month(1-12):')
day = input('enter the date(1-31):')
hour = input('enter the hour(0-23):')
minute = input('enter the minute(0-59):')
print()
if ((int(mon)<1 or int(mon)>12)
or (int(day)<1 or int(day)>31)
or (int(hour)<0 or int(hour)>23)
or (int(minute)<0 or int(minute)>59)):
print('invalid date and time, please set again!')
mon = input('enter the month(1-12):')
day = input('enter the date(1-31):')
hour = input('enter the hour(0-23):')
minute = input('enter the minute(0-59):')
reminderL.extend((mon, day, hour, minute))
reminder = ''
for element in reminderL:
if int(element)<10:
element = '0' + element
reminder = reminder + element + ' '
reminderList.append(reminder)
return reminderList
def reminder_main(wait_queue):
num = int(input('enter the numbers of reminder you want to set(1-9):'))
if num not in range(1,10):
print('invalid input, try again!')
num = int(input('enter the numbers of reminder you want to set(0-9):'))
List = setReminder(num)
print(List)
wait_queue.put('go-go-go') # unpause main thread
for i in range(num):
tim = time.strftime('%m %d %H %M ')
while tim not in List:
time.sleep(1)
tim = time.strftime('%m %d %H %M ')
print('Hello, it is time to take medicine!')
def main():
while True:
try:
option = int(input('Your choice? '))
except ValueError:
print('Cannot convert your choice into integer.')
else:
if option not in (1, 2, 3, 4):
print('Allowed options are 1, 2, 3, 4.')
else:
if option == 1:
pass
if option == 2:
pass
if option == 3:
wait_queue = queue.Queue()
# remainder thread
threading.Thread(
target=reminder_main,
kwargs={'wait_queue': wait_queue},
daemon=True).start()
wait_queue.get() # this is pause - waitng for any data
elif option == 4:
print('Exiting...')
break
if __name__ == '__main__':
# main thread
threading.Thread(
target=main).start()
Upvotes: 1