Search code examples
pythoncounterpersistent

Python InfiniteTimer Test Code on counting Failed Loop fails


I am trying to test my IP latency and using the InfiniteTimer I have just added a failCount global but when I try to increment in the tick() callback function I get an error.

File "C:\Users\ken38\OneDrive\Projects\Python\Pinger\ping_test3.py", line 17, in tick print("failCount: " + failCount) UnboundLocalError: local variable 'failCount' referenced before assignment

I assume this could be that the InfiniteTimer is in a separate thread and cannot see the global. Can anyone advise please.

from InfiniteTimer import InfiniteTimer
from ping3 import ping, verbose_ping
import os

failCount = 0

def tick():
    clear_screen()
    r = ping('1.1.1.1')  # Returns delay in seconds.
    fin = open("data2.txt", "a")
    if(isinstance(r, (int, float))):
        fin.write("%1.2f, \n" % (r * 1000))
    else:
        fin.write("%s, ping failed\n" % r)
        failCount = failCount + 1
    print("%1.2f" % (r *1000))
    print("failCount: " + failCount)
    fin.close()
# Example Usage
#t = InfiniteTimer(0.5, tick)
#t.start()
print('Kat is testing!')

t = InfiniteTimer(1.0, tick)
t.start()

def clear_screen():
    if os.name == 'nt':  # Windows
        os.system('cls')
    else:  # Linux/Unix
        os.system('clear')

I have found a work around but I do not understand why the original code failed. Adding a couple of defs to manage the counter and calling them from the callback tick() seems an oddity.

from InfiniteTimer import InfiniteTimer
from ping3 import ping, verbose_ping
import os

failCount = 0

def counterInc():
    failCount = failCount + 1
    return failCount

def getCounter():
    return failCount

def tick():
    failCount = 0
    clear_screen()
    r = ping('1.1.1.1')  # Returns delay in seconds.
    fin = open("data2.txt", "a")
    if(isinstance(r, (int, float))):
        fin.write("%1.2f, \n" % (r * 1000))
        failCount = getCounter()
    else:
        fin.write("%s, ping failed\n" % r)
        #failCount = failCount + 1
        failCount = counterInc()
    print("%1.2f" % (r *1000))
    print("failCount: %d" % failCount)
    fin.close()
# Example Usage
#t = InfiniteTimer(0.5, tick)
#t.start()
print('Kat is testing!')

t = InfiniteTimer(1.0, tick)
t.start()

def clear_screen():
    if os.name == 'nt':  # Windows
        os.system('cls')
    else:  # Linux/Unix
        os.system('clear')

Solution

  • To access GLOBAL VARIABLE, add this, only one time inside function.

    def tick():
        global failCount
    
        ...
        
        failCount = failCount + 1
        ...
    

    Alternative solution, variable as argument

    def tick(fail_counter):
        ...
        fail_counter += 1
        ...
    
    
    failCount = 0
    
    #call tick function with variable as argument
    t = InfiniteTimer(1.0, tick, [failCount])