[Tutor] RE: Base converter bases 2-62

Magnus Lyckå magnus@thinkware.se
Fri Jun 20 15:21:46 2003


At 11:47 2003-06-20 +0000, cino hilliard wrote:
>You are discouraging the old man. :--)

I believe in brutal honesty. :) If you are learning a new
programming languange as an "old man", I assume you are
open to challenges, and to finding new ways of doing things.

 From a practical point of view, I do see a point in being able
to handle different bases. But honestly not bases above 16. For
some kind of generic encryption or coding, there are lots of
existing formats already. See the binascii module for instance.

E.g.
 >>> binascii.b2a_uu('Cino Hilliard')
'-0VEN;R!(:6QL:6%R9   \n'
 >>> binascii.b2a_hqx('Cino Hilliard')
'3fPZEb")D@aXD@&bC!'
 >>> binascii.b2a_hex('Cino Hilliard')
'43696e6f2048696c6c69617264'
 >>> binascii.b2a_base64('Cino Hilliard')
'Q2lubyBIaWxsaWFyZA==\n'

But I can surely agree that sheer amusement, learning and discovery
are quite good reasons for programming. Don't let me stop you.

What I'd really like to see concerning different bases, would be
that binary format was as well supported as hexadecimal. I.e.
just like we can do...

 >>> 0xbeef
48879
 >>> print "%x" % 123
7b
 >>> hex(123)
'0x7b'

...we should be able to do...

 >>> 0b10101010
 >>> print "%b" % 1323123
 >>> bin(123)

Particularly for learning, I think that

 >>> print "%b" % (0b110011 | 0b001100)
111111

is much easier to understand than

 >>> print 51 | 12
63


I wrote:
>>digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>
>>def numToBase(num, base):
>>     stack = []
>>     while num:
>>         stack.append(digits[num % base])
>>         num = num // base
>>     stack.reverse()
>>     return "".join(stack)
>>
>>This version only work for positive numbers though.
>>But it's fairly simple to handle negatives and zero
>>I think. I leave it as an excise to the reader...

>I like this. Here is my version.
>
>def numToBase(num, base):
>     import string
>     digits=""
>     for j in range(48,58):         #build digit table 0-9
>           digits = digits + chr(j)
>     for j in range(65,91):         #Add to digit table A-Z
>           digits = digits + chr(j)
>     for j in range(97,123):        #Add to digit Table a-z
>           digits = digits + chr(j)
>     stack = []
>     while num:
>         stack.append(digits[num % base])
>         num = num // base
>     stack.reverse()
>     x =  "".join(stack)
>     print x
>#    return x

In think the explicit version where the string is stated as a literal
is better for several reasons:
  * First of all, my code is shorter and in my opinion easier to
    understand.
  * In actuality, it *is* a constant. It will look the same each time
    you create it.

>Example
>>>>convert.numToBase(680503772433971638008487115952059,62)
>3iEaIWRTFVzvd3szVet
>This agrees with the example above in my code. Now, how do you go back?
>Well long(s,radix) will work up to base 36. I will figure it out.

Ok, if you want to go beyond base 36, you need to code the
other way as well. Jeff Shannon already mentioned that you
can use the string method index for that.

"0123456789ABC".index("B") will return 11.

That's a start... The rest is just like above but backwards... :)


--
Magnus Lycka (It's really Lyckå), magnus@thinkware.se
Thinkware AB, Sweden, www.thinkware.se
I code Python ~ The Agile Programming Language