On Sat, 22 Jan 2005 00:45:19 +1000, Nick Coghlan <[EMAIL PROTECTED]> wrote:Here's an interesting twiddle, though (there's probably already something along these lines in the cookbook):
Looks like you also played with this problem, after Alex posted a request for alternative one-liner solutions to a question on an Italian newsgroup last October? ("show_base" reminded me of "number_in_base")
http://groups-beta.google.com/groups?hl=en&lr=&q=number_in_base&qt_s=Search+Groups
See, I knew I wouldn't be the first one to think of it :)
I stole some ideas from that thread to add to the new version down below (I did not, however, try to make the function expressible as a one-liner, since, after the function has been defined, *using* it is a one-liner!)
Hm, learn something every day ;-) It didn't occur to me that a string multiplied by a negative number would default nicely to the same result as multiplying by zero.
Where'd I learn that trick?. . . oh, that's right, Facundo used it when working out the string representation for Decimal. It certainly makes padding to a desired minimum field width pretty easy.
Of course, this is the prefixed-sign and absolute value representation, which is no good if you are using base 2, 8, or 16 to get an idea of underlying bits in a negative two-s complement representation.
Dealing with negative numbers isn't really needed for printing a string as binary , since ord() returns only positive results.
However, we should be able to add complement formatting fairly easily:
Py> def show_base(val, base, min_digits=1, complement=False, ... digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"): ... if base > len(digits): raise ValueError("Not enough digits for base") ... negative = val < 0 ... val = abs(val) ... if complement: ... sign = "" ... max = base**min_digits ... if (val >= max) or (not negative and val == max): ... raise ValueError("Value out of range for complemented format") ... if negative: ... val = (max - val) ... else: ... sign = "-" * negative ... val_digits = [] ... while val: ... val, digit = divmod(val, base) ... val_digits.append(digits[digit]) ... result = "".join(reversed(val_digits)) ... return sign + ("0" * (min_digits - len(result))) + result ... Py> show_base(10, 2) '1010' Py> show_base(-10, 2) '-1010' Py> show_base(10, 2, 8) '00001010' Py> show_base(-10, 2, 8) '-00001010' Py> show_base(10, 2, 8, complement=True) '00001010' Py> show_base(-10, 2, 8, complement=True) '11110110' Py> show_base(10, 16, 2, complement=True) '0A' Py> show_base(-10, 16, 2, complement=True) 'F6' Py> show_base(127, 16, 2, complement=True) '7F' Py> show_base(-127, 16, 2, complement=True) '81' Py> show_base(255, 16, 2, complement=True) 'FF' Py> show_base(-255, 16, 2, complement=True) '01' Py> show_base(256, 16, 2, complement=True) Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 10, in show_base ValueError: Value out of range for complemented format Py> show_base(-256, 16, 2, complement=True) '00' Py>
Cheers, Nick.
-- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.skystorm.net -- http://mail.python.org/mailman/listinfo/python-list