Python Forum
Ending a thread from another thread
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Ending a thread from another thread
#1
I have a timer and it is supposed to end the function given to it in a parameter. I don't know how though. Can someone help me. Line 8
import time
import random
import threading

def Timer(Time, func):
    time.sleep(int(Time) + 3)
    print('Times up!')
    #End func here
    
def Math(MIN1, MAX1, MIN2, MAX2):
    MIN1 = int(MIN1)
    MIN2 = int(MIN2)
    MAX1 = int(MAX1)
    MAX2 = int(MAX2)
    print('Alright, problem incoming in ')
    time.sleep(1)
    print('3')
    time.sleep(1)
    print('2')
    time.sleep(1)
    print('1')
    time.sleep(1)
    firstNum = random.randint(MIN1, MAX1)
    secNum = random.randint(MIN2, MAX2)
    print('%s * %s' %(firstNum, secNum))
    inAnswer = input()
    answer = firstNum * secNum
    if inAnswer == answer:
        print('Great Job!')
    else:
        print('Not quite')
    
def Main():
    print('Welcome, this program is meant to help the learning of or refining of multiplication facts')
    time.sleep(2)
    
    while True:
        timer = input('Please type the time you would like to give yourself for each problem (Seconds)\n')
        time.sleep(1)
        try:
            int(timer)
            break
        except:
            print("Please Enter a Number")
            
    while True:
        minimum1 = input('Please type the lowest number you want for your first number\n')
        time.sleep(1)
        try:
            int(minimum1)
            break
        except:
            print("Please Enter a Number")
            
    while True:
        maximum1 = input('Please type the highest number you would like for your first number\n')
        time.sleep(1)
        try:
            int(maximum1)
            break
        except:
            print("Please Enter a Number")
            
    while True:
        minimum2 = input('Please type the lowest number you want for your second number\n')
        time.sleep(1)
        try:
            int(minimum2)
            break
        except:
            print("Please Enter a Number")
        
    while True:
        maximum2 = input('Please type the highest number you would like for your second number\n')
        time.sleep(1)
        try:
            int(maximum2)
            break
        except:
            print("Please Enter a Number")
    
    playing = True
    while playing:
        M = threading.Thread(target=Math, args=(minimum1, maximum1, minimum2, maximum2))
        T = threading.Thread(target=Timer, args=(timer, M))
        T.start()
        M.start()
        M.join()
        T.join()
        while True:
            time.sleep(1)
            yesNo = input('Would you like to continue - y/n\n')
            if yesNo.lower() == 'n':
                playing = False
                break
            elif yesNo.lower() != 'y' and yesNo.lower() != 'n':
                print('Invalid Answer')
    
Main()
Reply
#2
see: https://www.oreilly.com/library/view/pyt...06s03.html
Reply
#3
I don't see how I would implement this.
Reply
#4
I think you're trying to exit from user input if the user doesn't answer after a few seconds. This is a difficult subject. I found a nice snippet HERE with a decorator. I think its worth remembering this.

import multiprocessing
import multiprocessing.pool
 
def timeout(seconds=10):
    def decorator(func):
        def wrapper(*args, **kwargs):
            pool = multiprocessing.pool.ThreadPool(processes=1)
            results = pool.apply_async(func, args, kwargs)
            pool.close()
            try:
                return results.get(seconds)
            except multiprocessing.TimeoutError:
                raise OSError('Timeout expired after: %s' % seconds)
            finally:
                pool.terminate()
        return wrapper
    return decorator
 
@timeout(3)
def long_func():
    try:
        input('Please type your name: ')
    except OSError:
        print("We shouldn't be here! Strange error.")
    print('end of long_func')
 
try:
    long_func()
except OSError as e:
    print('\nToo late!")
Reply
#5
So I used that and put it all togather. This is what I got but it doesn't work. I have two problems. I know why I have one, but I don't know why I have the other.
Problem 1 - Words merge together. It prints time up and merges it with another print (because it finishes the function)
Problem 2 - The timeout is not what is given
Can someone tell me how to fix this
import time
import random
import threading
import multiprocessing
import multiprocessing.pool

#######################################################################################################
correctResponse = ['Great Job!', 'Awesome', 'Wow!', 'Doing Good', 'You\'re smart', 'Correct!']
wrongResonse = ('Way off', 'Better luck next time... or maybe not', 'That\'s not it', 'Well... No', 'Not quite', 'You were kinda close', 'Almost', 'So Close!')
notClose = [wrongResonse[0], wrongResonse[1], wrongResonse[2], wrongResonse[3]]
close = [wrongResonse[4], wrongResonse[5]]
almost = close = [wrongResonse[6], wrongResonse[7]]
wrong = False

#######################################################################################################
def timeout(seconds=10):
    def decorator(func):
        def wrapper(*args, **kwargs):
            pool = multiprocessing.pool.ThreadPool(processes=1)
            results = pool.apply_async(func, args, kwargs)
            pool.close()
            try:
                return results.get(seconds)
            except multiprocessing.TimeoutError:
                raise OSError('Timeout expired after: %s' % seconds)
            finally:
                pool.terminate()
        return wrapper
    return decorator

######################################################################################################
print('Welcome, this program is meant to help the learning of or refining of multiplication facts')
time.sleep(2)
while True:
    timeWait = input('Please type the time you want for each expression\n')
    time.sleep(1)
    try:
        int(timeWait)
        break
    except:
        print('"%s" is not a valid answer, please answer with an int value' %timeWait)
        time.sleep(1)
#######################################################################################################

@timeout(int(timeWait))
def Math(MIN1, MAX1, MIN2, MAX2):
    MIN1 = int(MIN1)
    MIN2 = int(MIN2)
    MAX1 = int(MAX1)
    MAX2 = int(MAX2)
    while True:
        print('Alright, problem incoming in ')
        time.sleep(1)
        print('3')
        time.sleep(1)
        print('2')
        time.sleep(1)
        print('1')
        time.sleep(1)
        firstNum = random.randint(MIN1, MAX1)
        secNum = random.randint(MIN2, MAX2)
        print('%s * %s' %(firstNum, secNum))
        inAnswer = input()
        answer = int(firstNum) * int(secNum)
        try:
            if int(inAnswer) == answer:
                if not wrong:
                    print(random.choice(correctResponse))
            else:
                if not wrong:
                    sub = answer - inAnswer
                    if sub > 10 or sub < -10:
                        print(random.choice(notClose))
                    elif sub > 5 or sub < -5:
                        print(random.choice(close))
                    elif sub == 1 or sub == -1:
                        print(random.choice(almost))
            break
        except:
            print('%s is not a valid answer. Please answer w/ an int value' %inAnswer)

#######################################################################################################
def Main():
    while True:
        minimum1 = input('Please type the lowest number you want for your first number\n')
        time.sleep(1)
        try:
            int(minimum1)
            break
        except:
            print("Please Enter a Number")
            time.sleep(1)
            
    while True:
        maximum1 = input('Please type the highest number you would like for your first number\n')
        time.sleep(1)
        try:
            int(maximum1)
            break
        except:
            print("Please Enter a Number")
            time.sleep(1)
            
    while True:
        minimum2 = input('Please type the lowest number you want for your second number\n')
        time.sleep(1)
        try:
            int(minimum2)
            break
        except:
            print("Please Enter a Number")
            time.sleep(1)
        
    while True:
        maximum2 = input('Please type the highest number you would like for your second number\n')
        time.sleep(1)
        try:
            int(maximum2)
            break
        except:
            print("Please Enter a Number")
            time.sleep(1)
    
    playing = True
    while playing:
        try:
            Math(minimum1, maximum1, minimum2, maximum2)
        except OSError as e:
            wrong = False
            print('The alotted time expired before you answered')
        
        while True:
            time.sleep(1)
            yesNo = input('Would you like play again - y/n\n')
            if yesNo.lower() == 'n':
                playing = False
                break
            elif yesNo.lower() != 'y' and yesNo.lower() != 'n':
                print('Invalid Answer')

#######################################################################################################
Main()
Reply
#6
I prefer a GUI because it can handle multiple objects
    import tkinter as tk     ## Python 3.x
    from tkinter import font

    class Timer_Test() :
         def __init__(self, master=None) :
            self.master = master
            self.app_font = font.Font(name='Cursor', size=12)
            self.ctr=20
            self.name=""
            self.start_timer()
            self.init_window()

         def init_window(self):
            tk.Label(self.master, text="Enter something\nYou have 10 seconds",
                    bg="yellow", font=self.app_font).grid(sticky="nsew")
            self.ent=tk.Entry(self.master, bg="lightblue", font=self.app_font)
            self.ent.grid(row=1, column=0)
            tk.Button(self.master, text="Use this name", font=self.app_font,
                     command=self.name_entered, activebackground="LightSalmon2",
                     bg="lightyellow").grid(row=10, column=0, sticky="nsew")
            self.ent.focus_set()

         def name_entered(self):
            """ button calls this function which stores the name entered
                and quits
            """
            self.name=self.ent.get()
            self.master.quit()

         def start_timer(self):
            """ countdown timer and a label that displays time left
                in a different window
            """
            top=tk.Toplevel()
            self.lbl=tk.Label(top, bg="orange", font=self.app_font, width=10)
            self.lbl.grid()
            self.update_timer()

         def update_timer(self):
            """
                This function repeatedly calls itself until time has
                expired, and then it shuts down the GUI
            """
            self.ctr -= 1
            self.lbl["text"]=int(self.ctr/2)
            if self.ctr > 0:  ## 10 seconds
                self.master.after(500, self.update_timer)  ## 1/2 second
            else:             ## time is up
                self.master.quit()

    root = tk.Tk()
    app = Timer_Test(root)
    root.mainloop()

    if len(app.name):
        print("After Exit, name =", app.name) 
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Anyway to stop a thread and continue it? dimidgen 2 263 Mar-18-2024, 10:53 AM
Last Post: DeaD_EyE
  drawing a table with the status of tasks in each thread pyfoo 3 356 Mar-01-2024, 09:29 AM
Last Post: nerdyaks
  Error: can't start new thread maha2 0 1,384 Jun-13-2023, 12:26 PM
Last Post: maha2
  add svg to 2 thread program and display tabel in GUI Nietzsche 5 1,360 May-06-2023, 01:25 PM
Last Post: Nietzsche
  Thread Limits . . . JohnnyCoffee 10 1,574 Mar-03-2023, 04:07 AM
Last Post: jefsummers
  While loop not ending (Best of 10 dice game) K3nidi 3 1,457 Jul-09-2022, 09:53 AM
Last Post: K3nidi
  How to use Thread() ? Frankduc 7 1,983 May-17-2022, 04:51 PM
Last Post: Frankduc
  How to immediately kill and restart a thread while using a time.sleep() inside it? philipbergwerf 4 3,452 Feb-07-2022, 04:16 PM
Last Post: Gribouillis
  Process doesn't work but Thread work ! mr_byte31 4 2,556 Oct-18-2021, 06:29 PM
Last Post: mr_byte31
  Reddit bot thread Gabriel777 0 24,970 Sep-20-2021, 02:57 AM
Last Post: Gabriel777

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020