Danvin Lee Qicheng
Danvin Lee Qicheng

Reputation: 57

Python realtime timer

Could anybody advise me on converting the Java Timer class to Python? Currently I am converting a Java program to a Python script. However, Python does not have the Timer/TimerTask library (if it does have this, please enlighten me. Thanks!). I need to be able to reset the Timer. Java has Timer.cancel, but Python doesn't have this. Is there any replacement for it?

            timer.cancel();
            timer = new Timer("Printer");
            MyTask t = new MyTask();
            timer.schedule(t, 0, 1000);

Java script timer

    class Timerclass extends TimerTask {
    //times member represent calling times.
    private int times = 0;


    public void run() {
        times++;
        if (times <= 5) {
             System.out.println(""+times);
        } else {
            this.cancel();
            //Stop Timer.
            System.out.println("Timer Finish");

        }

    }
}

Currently my code

import time
import threading

class Variable:
    count = 0
    people = 0
    times = 0

def enter():
    if int(Variable.count == 1):
        print("Entered")
        t = threading.Timer(5.0, countdown)
        t.start()
    else:
        print("Entered +1")
        t.clear() // Stuck Help 
        t = threading.Timer(5.0, countdown)
        t.start()
def out():
    if int(Variable.count > 0):
        print("Exited")
    elif int(Variable.count < 0):
        print("Error")

def countdown():
    print("TIMEUP")

while True:
    sensor1 = input("Sensor 1: ")
    sensor2 = input("Sensor 2: ")
    Variable.count+=1

    if int(sensor1) == int(sensor2):
        Variable.count -= 1
        print(Variable.count)
        print("error")
    elif int(sensor1) == 1:
        Variable.people += 1
        print(Variable.people)
        enter()
    elif int(sensor2) == 1:
        Variable.people -= 1
        print(Variable.people)
        out()
    else:
        print("Error")

i have one problems that i'm stuck in i need to stop the current counting and start a new one whenever the method call

Basically what i want or im looking out for is when i recall this method it will reset or cancel any existing and recount again

Update latest

import time
import threading

class Variable:
    count = 0
    people = 0
    times = 0

def countdown():
    print("TIMEUP")

t = threading.Timer(5.0, countdown)   
def enter():
    if int(Variable.count == 1):
        print("Entered")
        t.start()
    else:
        print("Entered +1")
        t.cancel()
        t.join()         # here you block the main thread until the timer is completely stopped
        t.start()

def out():
    if int(Variable.count > 0):
        print("Exited")
    elif int(Variable.count < 0):
        print("Error")

while True:
    sensor1 = input("Sensor 1: ")
    sensor2 = input("Sensor 2: ")
    Variable.count+=1

    if int(sensor1) == int(sensor2):
        Variable.count -= 1
        print(Variable.count)
        print("error")
    elif int(sensor1) == 1:
        Variable.people += 1
        print(Variable.people)
        enter()
    elif int(sensor2) == 1:
        Variable.people -= 1
        print(Variable.people)
        out()
    else:
        print("Error")

Anybody can spot my ,istake im getting this error but i t.clear() the process

in start raise RuntimeError("threads can only be started once") RuntimeError: threads can only be started once

Upvotes: 0

Views: 8782

Answers (2)

dano
dano

Reputation: 94961

Python actually has a class for this, which includes a cancel method: threading.Timer. It seems to be close enough to the Java Timer class for your needs (The Java Timer also runs in background thread). Here's the example usage from the docs:

def hello():
    print "hello, world"

t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed

Edit:

The problem with your updated code is that you're trying to use the same Timer object more than once. That may be possible in the Java implementation, but in Python you can't reuse a Thread object (Timer is a Thread subclass). You'll need to create a new Timer object after you join() it. Like this:

t = threading.Timer(5.0, countdown)   
def enter():
    global t  # You need this to tell Python that you're going to change the global t variable. If you don't do this, using 't = ..' will just create a local t variable.
    if int(Variable.count == 1):
        print("Entered")
        t.start()
    else:
        print("Entered +1")
        t.cancel()
        t.join()         # here you block the main thread until the timer is completely stopped
        t = threading.Timer(5.0, countdown)
        t.start()

Upvotes: 1

A.J. Uppal
A.J. Uppal

Reputation: 19284

I would suggest using the time module for something like this:

from time import time, sleep
from datetime import datetime, timedelta

nowtime = time()

#Put your script here
x = 1
for k in range(1000):
        x+=1
        sleep(0.01)

sec = timedelta(seconds=int(time()-nowtime))
d = datetime(1,1,1)+sec

print("DAYS:HOURS:MIN:SEC")
print("%d:%d:%d:%d" % (d.day-1, d.hour, d.minute, d.second))

This assigns the time in seconds at the beginning to a variable, and after the main script has finished, it subtracts the previous time from the current time and formats it in days, hours, minutes, and seconds.

Here is it running:

bash-3.2$ python timing.py
DAYS:HOURS:MIN:SEC
0:0:0:10
bash-3.2$ 

You could also use the Threading module, which has a built-in cancel method:

>>> import threading
>>> def hello():
...     print "This will print after a desired period of time"
... 
>>> timer = threading.Timer(3.0, hello)
>>> timer.start() #After 3.0 seconds, "This will print after a desired period of time" will be printed
>>> This will print after a desired period of time

>>> timer.start()
>>> timer = threading.Timer(3.0, hello)
>>> timer.start()
>>> timer.cancel()
>>> 

Upvotes: 1

Related Questions