Representing enum style values w/ pretty printing?

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
ldmoretti
Posts: 5
Joined: Fri Mar 26, 2021 1:34 am

Representing enum style values w/ pretty printing?

Post by ldmoretti » Fri Mar 26, 2021 1:56 am

I've got a board that's sending "magic values" across the wire to my board running MicroPython. I've got these currently represented as constants in a class. I'd like to have a string conversion function that pretty prints the values but I'm having trouble figuring out how to do it.

Example:

Code: Select all

class CommandCodes:
	Death		= const(0x0001)
	Life		= const(0x0002)
	Universe	= const(0x0040)
	Everything	= const(0x0042)
	
	# something else here to make it prettily convert to a string...
	
value = CommandCodes::Everything
print( str(value))  # I'd like it to print "Everything"

I tried using a dict inside my class but didn't get it to work. I'm guessing my __str__ function has an issue.

Code: Select all

	d = {Death:'Death', Life:'Life', Universe:'Universe', Everything:'Everything'}
	
	def __str__(self)
		return d[self]
If there's a more Pythonic to do it I'm not tied to the representation above. I've been doing C & C++ for a long time but I'm fairly new to Python so I'm probably missing something easy.

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

Re: Representing enum style values w/ pretty printing?

Post by pythoncoder » Fri Mar 26, 2021 9:33 am

I'm afraid that "fairly new to Python" is rather an understatement ;) That script is a weird mix of C and Python.

The biggest error is perhaps your misunderstanding of the __str__ method which should return a pretty string showing the entire object. But you never create an object instance, so self (the reference to an instance) doesn't exist. There are numerous other errors so I suggest you follow an online course or buy a book to learn the language. As a C programmer you'll find it easy. The following script does something akin to what you're after:

Code: Select all

class CommandCodes:
    Death = const(0x0001)
    Life = const(0x0002)
    Universe = const(0x0040)
    Everything = const(0x0042)

    def __init__(self):  # Need an instance to create the dictionary - or could use a classmethod
        self.d = {self.Death:'Death', self.Life:'Life', self.Universe:'Universe', self.Everything:'Everything'}

    def __str__(self):
        s = ''
        for key in sorted(self.d.keys()):
            ss = '{:04x} : {}'.format(key, self.d[key])
            ''.join((s, ss))
            print(s, ss)
        return s

    def __getitem__(self, key):  # Enable dict-like access
        return self.d[key]

command_codes_instance = CommandCodes()
print(str(command_codes_instance))  # The entire object
print(command_codes_instance[Everything])  # A single value
print(CommmandCodes.Everything)  # Don't need an instance here
One point which may seem trivial but isn't is this. Use spaces rather than tabs. Python is strict about indentation. Using tabs means that one day you'll inadvertently mix spaces and tabs getting code which looks good but won't compile. The standard is four spaces.
Peter Hinch
Index to my micropython libraries.

Post Reply