0

I'm in a situation where I have to use Python to read and write to an EEPROM on an embedded device. The first page (256 bytes) is used for non-volatile data storage. My problem is that the variables can vary in length, and I need to read a fixed amount.

For example, an string is stored at address 30 and can be anywhere from 6 to 10 bytes in length. I need to read the maximum possible length, because I don't know where it ends. What that does is it gives me excess garbage in the string.

data_str = ee_read(bytecount)
dbgmsg("Reading from EEPROM: addr = " + str(addr_low) + " value = " + str(data_str))

> Reading from EEPROM: addr = 30 value = h11c13����

I am fairly new to Python. Is there a way to automatically chop off that data in the string after it's been read in?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
linsek
  • 3,334
  • 9
  • 42
  • 55

1 Answers1

6

Do you mean something like:

>>> s = 'Reading from EEPROM: addr = 30 value = h11c13����'
>>> s
'Reading from EEPROM: addr = 30 value = h11c13\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd'
>>> filter(lambda x: ord(x)<128,s)
'Reading from EEPROM: addr = 30 value = h11c13'

On python3, you'll need to to join the string:

''.join(filter(lambda x: ord(x)<128,s)

A version which works for python2 and python3 would be:

''.join(x for x in s if ord(x) < 128)

Finally, it is concieveable that the excess garbage could contain printing characters. In that case you might want to take only characters until you read a non-printing character, itertools.takewhile could be helpful...

import string #doesn't exist on python3.x, use the builtin `str` type instead.
from itertools import takewhile

printable = set(string.printable)  
''.join(takewhile(lambda x: x in printable, s))
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • As a side note, I was **SHOCKED** with `filter` returned a string ... I kind of wish they had kept that behavior in python3.x ... – mgilson Jan 18 '13 at 14:49
  • That is actually precisely what I'm looking for. The problem is I am working on an embedded system with some custom build of Python. I do not have access to the String functions in the library. So filter() is not available. – linsek Jan 18 '13 at 14:49
  • @njozwiak -- `filter` is a python builtin -- It's not in the string functions library. – mgilson Jan 18 '13 at 14:54
  • I see that now. It is still unavailable on this system. I think I am just going to have to do some pre-writing processing instead of post-reading. Either write a single byte for the length of the value or force data to be a static length all of the time. What a pain... – linsek Jan 18 '13 at 14:57
  • filter() can usually be replaced with a string comprehension and if-statement if need be. – Adam Cadien Jan 18 '13 at 15:09
  • 1
    @AdamCadien -- What is a "string comprehension"? -- The problem is that if OP doesn't have access to `filter` which is a python builtin, then it's pretty hard to guess what OP *does* have access to... – mgilson Jan 18 '13 at 15:11
  • @mgilson Obviously a string comprehension is a comprehensive string. Yet another lesson for me to not use SO when tired. – Adam Cadien Jan 18 '13 at 15:35
  • @mgilson Unfortunately, with this embedded device, I myself am not even sure what built-in Python functions are available and not. I was able to get his working just using static lengths. It was just the only viable option. I up-voted your answer and chose it as in any other situation, it will work. Thanks for the input. – linsek Jan 18 '13 at 20:35