Well, ASR33. OK, you win. I did use teletypes at university for a very short time (maybe one term). I remember a really interesting one that used spark discharge to print on the paper (how many people know that, at some point in time, terminals actually used paper and did not have a display?). It used a special waxed paper. The sparks would burn the wax to print. Crazy stuff.
Regarding bytes/bytearrays. When I need to get into the details I tend to use this simple hex dump tool I wrote. It makes it far easier to look at data, from, say, a communications protocol or a chip you might be talking to.
Code: Select all
# Hex dump bytes and bytearrays
_BYTES_PER_LINE = 16
_ADDRESS_WIDTH = 8
_SPACE_TO_HEX = 1
_SPACE_TO_ASCII = 1
_SPACE_BETWEEN_HEX = 1
_DISTANCE_TO_ASCII = _BYTES_PER_LINE * (2 + _SPACE_BETWEEN_HEX) + _SPACE_TO_ASCII
def hexdump(data:bytes, show_ascii:bool= True):
length = len(data)
if not length:
print("Empty")
return
# Print header
header = f"{' ' * (_ADDRESS_WIDTH + _SPACE_TO_HEX)}"
for i in range(_BYTES_PER_LINE):
header += f"{i:02X}{' ' * _SPACE_BETWEEN_HEX}"
if show_ascii:
header += f"{' ' * _SPACE_TO_ASCII}"
for i in range(_BYTES_PER_LINE):
header += f"{i:1X}"
print(header)
# Print hex dump
lines = length/_BYTES_PER_LINE
lines = int(lines) + bool(lines%1)
address = 0
for row in range(lines):
line = f"{address: 0{_ADDRESS_WIDTH}X}{' ' * _SPACE_TO_HEX}"
hex = ""
text = ""
chunk = min(_BYTES_PER_LINE, length)
for offset in range(chunk):
index = address + offset
if index >= length:
break
byte = data[index]
hex += f"{byte:02X}{' ' * _SPACE_BETWEEN_HEX}"
if show_ascii:
is_visible = 128 > byte >= 32
text += chr(data[index]) if is_visible else "."
line += hex + " " * (_DISTANCE_TO_ASCII - len(hex)) + text
address += _BYTES_PER_LINE
print(line)
print()
if __name__ == "__main__":
# Test
ba = bytearray([n%256 for n in range(35)])
hexdump(ba)
ba = bytes([n%256 for n in range(210)])
hexdump(ba)
There's room for improvement there. I chip away at it every so often. One interesting variant might be to make it work with 16 and 32 bit words, not just 8 bits. I have another variant that is protocol-aware and formats the output to make it easier to understand what might be going on.
One of the things I wish they had done with this issue of just working with bytes is to create the option for a mutable, yet fixed length, data structure. In other words, like bytes, yet mutable only for content. A bytes data structure in memory is far simpler than a bytearray and faster to process. This would be very useful for keeping memory allocation and garbage collection under control when you know that you can work with a fixed length buffer.
This isn't going to change, so, it is what it is. Even if I wanted to write my own, the problem is that so many routines return bytes() that you just can't escape the memory allocation overhead. Something like the serial readinto() method wants a bytearray --which brings into the fold the more complex data structure. Not sure if it will work with arrays, haven't tried it. Also not sure if that would be an advantage or not.
I'll be done with a fairly intensive project in a few weeks. After that I have a bunch of notes on things I would really like to look into and perhaps see if I may be able to contribute to the codebase. I've done a lot with data compression and expansion. There are some issues with the MicroPython unzip library that need to be fixed (or documented so people can use it). I have also identified a lot of opportunities to make the MicroPython faster. That might be one of my initial targets for contribution.