Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to eliminate the empty counter? [Python]

I have a question how to do so that after the number 6 there is not an empty "click" but immediately 1?

Currently it is like this 1,2,3,4,5,6,pausa,1,2,3… and I need to have: 1,2,3,4,5,6,1,2,3, Thank you for your help. I don’t know what the program "_" is doing at the moment and I don’t know how to go about it.

import tkinter as tk

class CounterTesting:

    def __init__(self, root):
        self.root = root
        self.counter = 0
        tk.Button(self.root, text="Hello", command=self.get_counter).pack()

    def get_counter(self):
        self.counter += 1
        length = 6

        if self.counter <= length:
            print('Number of counter:', self.counter )
        else:
            self.counter = 0

    def get_run(self):
        self.get_counter()
        self.root.mainloop()

if __name__ == '__main__':
    app = CounterTesting(tk.Tk())
    app.get_run()

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Well the issue is that in the button’s handler, you’re either displaying the new value:

        if self.counter <= length:
            print('Number of counter:', self.counter )

or resetting the counter:

        else:
            self.counter = 0

Since in the second case you’re not telling Python to display anything, it’s not displaying anything.

An easy solution would be to immediately call self.get_counter() again from your handler in the second case, and that would work, but it’s a bit… icky. Similarly you could reset the counter to 1 and print it immediately. Or even better reset to 1 before printing:

    def get_counter(self):
        self.counter += 1
        if self.counter > length:
            self.counter = 1

        print('Number of counter:', self.counter )

But a cleaner solution would be to make the counter correct "by construction". Usually this is done using the remainer operation (%): a % b will make a "wrap around" if it’s at least as large as b, so e.g. 5 % 6 is 5 and 6 % 6 is 0.

The way you can use it here is to ensure the counter is below 6 before incrementing it:

self.counter = (self.counter % 6) + 1
counter before remainder counter after
0 0 1
1 1 2
2 2 3
3 3 4
4 4 5
5 5 6
6 0 1

this way your counter will start at 0 before the first call, then it will keep cycling between 1 and 6. And you don’t need a condition anymore:

    def get_counter(self):
        self.counter = (self.counter % 6) + 1
        print('Number of counter:', self.counter )

Depending what you need the counter for, you could also use itertools.cycle on a collection between 1 and 6 e.g.

>>> c = itertools.cycle(range(1, 7))
>>> next(c)
1
>>> next(c)
2
>>> next(c)
3
>>> next(c)
4
>>> next(c)
5
>>> next(c)
6
>>> next(c)
1
>>> next(c)
2
>>> next(c)
3
>>> next(c)
4

The drawback of this solution is that you can’t ask cycle for its "current value". With your example this is not an issue as the current value is only displayed once, but if you otherwise need to operate on the current value then you’ll need to store it separately.

The advantage is that your "producer" of values now can be anything (which is iterable), it doesn’t need to be something that can be incremented by one.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading