Threading in Python with Timed While Loop

140 Views Asked by At

A similar question was asked earlier but it didn't provide the correct answer.

I am trying to code to test threading in Python in which a ticker ticks every second. I am trying to keep the ticker function named 'clicking' running in a thread whose output is continously being incremented by one every second.

import time
import threading
import queue

q = queue.Queue()

apple = 0
orange = 0    
rate = 1
clix = 0


def clicking(clix, rate):
    while True:
        time.sleep(1)
        clix += rate
        q.put(clix)

threading.Thread(target=clicking, args=(clix, rate)).start()
curr = q.get()
print(curr)

print('\nClicker Starting...')
endgame = False
while not endgame:

    print(f'Clix: {curr}')
    print('1. Apple : 10 clix | 2. Orange : 8 clix  |  3. Exit')
    ch = int(input('\nPurchase ID: '))

    if ch == 1 and curr >= 10:
        print(f'You have {curr} clix.')
        print('Got an Apple!')
        apple += 1
        rate += 1.1
        curr -= 10

    elif ch == 2 and curr >= 8:
        print('Got an Orange!')
        orange += 1
        rate += 1.2
        curr -= 8

    elif ch == 3:
        endgame = True
        stopflag = True
    else:
        print('Need more Clix')

But my otuput is always 1 instead of incrementing every second by defined rate. What am I missing? I even tried return clix in place of q.put(clix) but didn't work.

1

There are 1 best solutions below

1
On BEST ANSWER

the problem is that you are not updating the curr variable inside the while loop. But do notice that when you write "curr = q.get()" inside the while loop it will get the next value in the queue and not the last value (as I suppose you intend). I guess a more straightforward approach is to keep track on the seconds increment inside your while loop using time.time()

import time

apple = 0
orange = 0
rate = 1
clix = 0
curr = 0

last_ts = time.time()

print('\nClicker Starting...')
endgame = False
while not endgame:
    ts = time.time()
    curr += (ts - last_ts) * rate
    last_ts = ts

    print(f'Clix: {curr:.0f}')
    print('1. Apple : 10 clix | 2. Orange : 8 clix  |  3. Exit')
    ch = int(input('\nPurchase ID: '))

    if ch == 1 and curr >= 10:
        print(f'You have {curr:.0f} clix.')
        print('Got an Apple!')
        apple += 1
        rate *= 1.1 # I guess you meant x1.1
        curr -= 10

    elif ch == 2 and curr >= 8:
        print('Got an Orange!')
        orange += 1
        rate *= 1.2 # I guess you meant x1.2
        curr -= 8

    elif ch == 3:
        endgame = True
        stopflag = True
    else:
        print('Need more Clix')

this way you can exit properly also, notice that on your example even when the loop breaks the thread continues.

but in case you want to maintain a background thread, I suggest creating a class and storing class variables for the current counter and run condition.