0

I am new to python. It might seem little obvious but would like to know if there is any easier way in python to do this.

I am trying to count number entries to a function. Requirement is as below:

  • Every 5 sec a timer event is triggered through which callback (ev_5ms()) is inturn triggered
  • Wait until 20 secods and then clear the counter and start again

I am using the following code

counter = 0

"Callback"
def ev_5s():
if counter < 4:
    counter += 1
else
    counter = 0
    print('Send Message')

t = EventGenerator.TimerEventGenerator(1, ev_1s())
t.start()

Error Traceback:

Traceback (most recent call last):
File "C:/Users/i8479/Desktop/Python/HPP_SM.py", line 28, in <module>
t = EventGenerator.TimerEventGenerator(1, ev_1s())
File "C:/Users/i8479/Desktop/Python/HPP_SM.py", line 21, in ev_1s
if counter < 4:
UnboundLocalError: local variable 'counter' referenced before assignment

I am coding as I would do in c or cpp. How can I do this in python?

Skanda
  • 145
  • 4
  • 14
  • 3
    use `global counter` in the function to reference the counter variable. Anyway this is not a good practice – Netwave Apr 09 '19 at 07:48

3 Answers3

2

A pythonic way of doing this would be to have a decorator class, for example:

from functools import wraps
import time

class EventCounter(object):
  def __init__(self, reset_span):
    self.reset_span = reset_span
    self.running = False
    self.start_t = None
    self.counter = 0
  def __call__(self, f):
    @wraps(f)
    def wrapper(*args, **kwargs):
      if not self.running:
        self.start_t = time.time()
        self.counter += 1
        self.running = True
      elif (time.time() - self.start_t) > self.reset_span:
        self.start_t = time.time()
        self.counter = 0
      else:
        self.counter += 1
      print(f"Counter: {self.counter}")
      return f(*args, **kwargs)
    return wrapper


@EventCounter(2)
def foo():
  print("Foo")

Running:

for _ in range(5):
  foo()
  time.sleep(1)

results:

Counter: 1
Foo
Counter: 2
Foo
Counter: 0
Foo
Counter: 1
Foo
Counter: 0
Foo

Here you have the live example

Netwave
  • 40,134
  • 6
  • 50
  • 93
0

One of the solutions is global:

counter = 0

# Callback
def ev_5s():
    global counter
    if counter < 4:
        counter += 1
    else
        counter = 0
        print('Send Message')

t = EventGenerator.TimerEventGenerator(1, ev_1s())
t.start()
Waket Zheng
  • 5,065
  • 2
  • 17
  • 30
0

This means you are passing the variable counter into the function

Line to change

def ev_5s(counter):

Other line to change

t = EventGenerator.TimerEventGenerator(1, ev_1s(counter))
GILO
  • 2,444
  • 21
  • 47