Re-evaluating a string?

Tim Chase python.list at tim.thechases.com
Sun Jul 23 22:30:24 EDT 2006


> Thanks Tim, and John for your quick responses!

This is one of the better lists for getting quick (and usually 
helpful) responses.

> Tim, I tested your function and it works! Though I don't completely
> understand how. Could you possibly explain this?

 >>> def makeString(a):
...     return ''.join([type(x) != types.IntType and
...		str(x) or chr(x) for x in a])
...

The "boolean_expression and value1 or value2" is a common python 
idiom for something akin to C/C++/Java's ternary 
"boolean_expression? value1: value2" expression.  There are some 
gotchas (and workarounds for those gotchas) if value1 can be a 
"false" value (an empty string, a zero or empty list are good 
examples of this).  It pretty much boils down to joining all the 
elements of the list that is composed from "for every item in the 
list 'a', if it's not an int, just return the str() of it; and if 
it is an int, return the chr() of it".  It then smashes them all 
together with the join() and returns the resulting string.

> John, I test your "MEDUIM_WAY"and it works as well. How is it that
> putting the string together this way translates into a hex value to be
> transmitted to the serial port? When I manually tried to put a string
> together I couldn't get this to happen. I was trying:
> 
> controlString = '!SC' + '\\' + ch.__str__() + '\\' + rate.__str__()

The string-formatting "%c" expects a byte and prints the ascii 
character relating to the byte.  Also a good way to do things. 
Come to think of it, John had a lot of good ideas in his post. 
In your above code, the ch.__str__() creates a string 
representation of the number I presume is stored in ch.  The 
string representation of a number is simply a string containing 
that number:

 >>> x = 42
 >>> x.__str__()
'42'

Not very exciting.  And generally stylistically better to use 
str() in favor of the __str__() method call.

> also I noticed you added another line to the code which appears to
> split the low and high bytes for me? If so thanks! Could you also offer
> an explanation on how this works.

the divmod(x,y) function divides x by y, and returns a tuple. 
The first value of the tuple is the integer result of the 
division, and the second value of the tuple is the remainder. 
It's a one-step way of doing

	hi,lo = divmod(x,y)

works like a condensing of

	hi = x / y
	lo = x % y

> I tried a google search and couldn't
> get a decent explanation. 

Googling the python docs for "divmod" should do the trick.

http://www.google.com/search?q=site%3Adocs.python.org+divmod

returns several helpful hits wherein you can learn more than any 
sane person should care to know.  But the above primer should be 
enough to get you on your way.

I think, in the case of your example string, using John's 
suggestion of the %c formatting is the cleanest approach.  As 
such, I'd rework the move() function I suggested to simply be 
something like

def move(rate,lo,hi,chan=1):
	return "!SC%c%c%c%c\r" % (chan, rate, lo, hi)

where you possibly even just pass in the "position" parameter, 
and let the function do the splitting with something like

def move(rate,position,chan=1)
	hi,lo = divmod(position & 0xFFFF, 256)
	return "!SC%c%c%c%c\r" % (chan, rate, lo, hi)

or optionally use the struct module to unpack them.

Just a few more thoughts,

-tkc







More information about the Python-list mailing list