Writing a function to invert a boolean?

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
User avatar
ardthusiast
Posts: 25
Joined: Tue Feb 08, 2022 4:13 pm

Re: Writing a function to invert a boolean?

Post by ardthusiast » Thu Apr 28, 2022 12:34 am

karfas wrote:
Wed Apr 27, 2022 8:41 pm
ardthusiast wrote:
Wed Apr 27, 2022 5:06 pm
It's for an event handler. Basically, when the event handler is called, I want it to invert the value of a boolean. The event handler can only execute functions, so I cannot use the not operator.
I still don't get it. Maybe you can illustrate the problem with a few lines of code ?

When the event handler wants a function, you will need to provide that function.
Even a (hypothetical) generic invert() call operating via a reference or pointer will need a parameter (that you most likely can't provide, as the interface to the event handler is a function!).
Example:

Code: Select all

from event_handler import EventHandler

bool1 = True
bool2 = False

event = EventHandler()

def invert(boolean_ref):
	# boolean would be some reference to the boolean that I want to invert
	boolean_ref = not boolean_ref
	
# Add 'invert(reference_to_bool1)' and 'invert(reference_to_bool2)' as subscribers to the event
event += [invert, [reference_to_bool1]]
event += [invert, [reference_to_bool2]]

# Event is called
event()

# Print the values of bool1 and bool2, if it works as intended the output should be 'False True'
print(bool1, bool2)
I think @pythoncoder's idea of storing them in a list or array is probably what I will end up doing, maybe using a dictionary instead so that I can use names rather than numbers and provide myself with less confusion. So the above example would become something like this:

Code: Select all

from event_handler import EventHandler

booleans = {'bool1': True, 'bool2': False}

event = EventHandler()

def invert(boolean_ref):
	# boolean_ref is the key of the booleans dictionary
	booleans[boolean_ref] = not booleans[boolean_ref]
	
# Add 'invert(reference_to_bool1)' and 'invert(reference_to_bool2)' as subscribers to the event
event += [invert, ['bool1']]
event += [invert, ['bool2']]

# Event is called
event()

# Print the values of bool1 and bool2, if it works as intended the output should be 'False True'
print(booleans['bool1'], booleans['bool2'])

User avatar
karfas
Posts: 193
Joined: Sat Jan 16, 2021 12:53 pm
Location: Vienna, Austria

Re: Writing a function to invert a boolean?

Post by karfas » Thu Apr 28, 2022 5:44 am

I see. You didn't mention the handler function can get a parameter.

Why can't you use a class for handling the invertable flags ?

Code: Select all

class Bool():
    def __init__(self, name, value = False):
        self.value = value
        self.name = name
    def invert(self):
        self.value = not self.value
        print("value of {} is now {}".format(self.name, self.value))
    def value(self):
        return self.value

def handler(func):
    print("calling handler func")
    func()

flag1=Bool("f1")
flag2=Bool("f2", True)

# calling the event handler
handler(flag1.invert)
handler(flag2.invert)
This discussion looks purely academic for me, but is fun :-)
You will need a few minutes to create 2-3 functions for the flags you maybe need to invert.I doubt that you need more than that in a real-world program.
A few hours of debugging might save you from minutes of reading the documentation! :D
My repositories: https://github.com/karfas

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Writing a function to invert a boolean?

Post by pythoncoder » Thu Apr 28, 2022 9:08 am

You might be interested in my notes on bitmaps. There is a class BoolList that enables an array of bits to be created that can be set and cleared using array index notation. It is efficient, storing the bits in a bytearray, and non-allocating. So you can write

Code: Select all

arr = BoolList()  # By default stores up to 256 bits
arr[100] = True
if arr[120]:
    arr[125] = not arr[125]  # Toggle a bit
Peter Hinch
Index to my micropython libraries.

User avatar
ardthusiast
Posts: 25
Joined: Tue Feb 08, 2022 4:13 pm

Re: Writing a function to invert a boolean?

Post by ardthusiast » Thu Apr 28, 2022 1:10 pm

karfas wrote:
Thu Apr 28, 2022 5:44 am
Why can't you use a class for handling the invertable flags ?
Could also work. I had considered that, and it does seem like a nicer method overall, but I think I'm going to go with the array/list/dictionary method.
karfas wrote:
Thu Apr 28, 2022 5:44 am
This discussion looks purely academic for me, but is fun :-)
This is actually for a (rather complicated) project that I'm working on. Basically, I've got a robot that needs to autonomously navigate a random maze. I've been using event handlers to allow for communication between different instances of different classes without constantly testing the value of a variable (doing this inside of a class would mess with the execution of my program). I've finally come to the point where a class is communicating directly with the main code. Having a while loop in the main script won't affect the execution of the rest of my code, so I'm trying to avoid event handlers as much as possible because programming a robot's behavior using events is painful (and debugging them is even worse). But this is a class that gathers information from a bunch of other classes,..., and so most things that happen within this class have to be triggered by events in other classes. So I have to have the main script watch for the value of a boolean whose value is inverted by an event handler being triggered in some other class.

Anyways, this is what I'm doing now, and it works:

Code: Select all

booleans = {
                            'bool1': True,
                            'bool2': False,
                            'it_works': False
		  }
		  
def inv_bool(bool_key):
	booleans[bool_key] = not booleans[bool_key]
	
# Then I can invert the booleans
print(inv_bool('bool1'), inv_bool('bool2'), inv_bool('it_works'))

# Output: False True True
Thanks everyone for the suggestions!

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Writing a function to invert a boolean?

Post by pythoncoder » Fri Apr 29, 2022 10:52 am

ardthusiast wrote:
Thu Apr 28, 2022 1:10 pm
...I've been using event handlers to allow for communication between different instances of different classes without constantly testing the value of a variable (doing this inside of a class would mess with the execution of my program)....
Have you considered using uasyncio? This is usually the best way to do this kind of thing. See also this tutorial.
Peter Hinch
Index to my micropython libraries.

User avatar
ardthusiast
Posts: 25
Joined: Tue Feb 08, 2022 4:13 pm

Re: Writing a function to invert a boolean?

Post by ardthusiast » Fri Apr 29, 2022 12:11 pm

Yes, I was using that before I had the idea to try event handlers. I started to get some major performance issues when using more than three coroutines, so I had to look for other methods. I was able to completely replace uasyncio by utilizing timers and event handlers. And, at this point I've written so much code that it would be hard to go through and replace all the event handlers.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Writing a function to invert a boolean?

Post by pythoncoder » Sat Apr 30, 2022 9:17 am

Fair enough - I can't argue with code that works ;)

But in general uasyncio can handle very many more than three coroutines, and on most platforms this benchmark runs 1000.
Peter Hinch
Index to my micropython libraries.

Post Reply