2

I'm working with the schedule package built by Dan Bader and I'm not sure how to pass a counter into the package.

Here is the basic example of how this is used:

def job(message="stuff"):
    print("I'm working on:", str(message))

schedule.every(10).seconds.do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

So this prints I'm working on: stuff every 10 seconds which is great but what its missing for my application is a counter. I'd like to count every time a job is run and pass that into my function but I haven't been able to figure that out.

This was my latest attempt:

def job(count = 0):
    print(count)

count = 0 

schedule.every(10).seconds.do(job, count)

while True:
    schedule.run_pending()
    time.sleep(1)
    count += 1

I thought that having count as a parameter and looping it within the while loop would work but it did not.

At the end of the day, I need a platform that will allow me to constantly run a function at some interval and keep track of how many times the job has run.

Any help would be much appreciated

madsthaks
  • 2,091
  • 6
  • 25
  • 46

2 Answers2

2

Well, not sure it's the more obvious way, but I would do something like

import schedule
import time

class Count(object):

    def __init__(self):
        self._count = 0

    def __str__(self):
        count = self._count
        self._count += 1
        return str(count)

def job(count):
    print(count)

count = Count()
schedule.every(1).seconds.do(job, count)

while True:
    schedule.run_pending()

Count's instance just increment itself when printed, so if you are sure to print it only in job you keep track of how many times it was ran.

The only real pro VS the dict solution is you don't have to compute anything in job - count handles itself alone.


 Edit

Since some SO folks seems to like my idea even if (and that's clearly true) it hide some functional aspects of the counter (nobody expect to handle an instance that increment an integer when printed) here is a little update that makes it less tricky, less confusing, in brief: better.

class CountLogger(object):

    def __init__(self):
        self._count = 0

    def log(self, message = ''):
        print('{}: {}'.format(self._count, message))
        self._count += 1

It does almost the exact same thing, but calling CounterLogger.log() to see an integer getting incremented is less puzzling.

Just replace print(count) by count.log().

Community
  • 1
  • 1
Arount
  • 9,853
  • 1
  • 30
  • 43
  • I like the idea :) Though, in a larger project, I'd be careful with it, because it hides a significant portion of the functionality. Just one single string conversion to many, for whatever reason ... screws things up pretty badly. – s-m-e Dec 19 '17 at 16:19
  • This works for the most part but what if I needed to use that count in some calculation. – madsthaks Dec 19 '17 at 16:41
  • Well, you can with both solution I proposed: `count._count` gives you access to the integer value of the counter. So after the `while True` you can make compute – Arount Dec 19 '17 at 16:43
  • Its a string value that I can't seem to change. Sorry, I don't use classes that often so I may be missing something simple. – madsthaks Dec 19 '17 at 17:17
  • No, it's an integer, you can update it: `count = CountLogger(); count._count = 100; count.log()` will output `100:`. – Arount Dec 19 '17 at 19:53
1

You can use a mutable object like a dictionary to achieve what you want. (Your original count variable is an integer, which is NOT mutable in Python.) The following works:

import schedule
import time

store = {'count': 0}

def job(data):
    data['count'] += 1
    print(data['count'])

schedule.every(10).seconds.do(job, store)

while True:
    schedule.run_pending()
    time.sleep(1)
s-m-e
  • 3,433
  • 2
  • 34
  • 71