473,698 Members | 2,411 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

"number-in-base" ``oneliner''

I hesitate a bit to post this, but... on the Italian Python NG, somebody
was asking whether there was any way to convert an integer number x into
a string which represents it in an arbitrary base N (given a sequence
with a len of N that gives the digits to use) as "a single expression".

I haven't found a really general way, much less a clear one, but, the
best I have so far is...:

def number_in_base( x, N, digits, maxlen=99):
return '-'[x>=0:] + (
(x and ''.join([digits[k%N] for i in range(maxlen)
for k in [abs(x)//N**i] if k>0])[::-1]
) or digits[0])

Besides the lack of clarity, the obvious defect of this approach is that
darned 'maxlen' parameter -- but then, since I can have only a 'for',
not a 'while', in a list comprehension or generator expression, and I
don't think recursion qualifies as 'a single expression'...:-(

Anyway, improvements and suggestions welcome, thanks!
Alex
Jul 18 '05
21 2151
On Sat, 30 Oct 2004 09:02:14 GMT, bo**@oz.net (Bengt Richter) wrote:
On Sat, 30 Oct 2004 07:48:34 GMT, bo**@oz.net (Bengt Richter) wrote:
On Sat, 30 Oct 2004 06:07:23 GMT, bo**@oz.net (Bengt Richter) wrote:
[...]
Maybe something useful in this? Not very tested (and not terribly clear either ;-)

>>> def number_in_base( x, N, digits):
... return x==0 and digits[0] or '-'[:x<0] + ''.join([d for d in iter(
... lambda qr=[abs(x),0]:qr[0] and (
... qr.__setslice__ (0,2,divmod(qr[0],N)) or digits[qr[1]])
... , 0)][::-1])
...


Alternatively , a little more compactly (though I feel guilty about the -1 ;-):
>>> def number_in_base( x, N=10, digits='0123456 789ABCDEF'):

... return '-'[:x<0] + ''.join(list(it er(lambda qr=[abs(x),-1]: (qr[0] or qr[1]<0) and (
... qr.__setslice__ (0,2,divmod(qr[0],N)) or digits[qr[1]]), False))[::-1])
...


Yet another, prefixing digits instead of joining reversed list:
def number_in_base( x, N=10, digits='0123456 789ABCDEF'): ... return '-'[:x<0]+reduce(lambda s,c:c+s, iter(lambda qr=[abs(x),-1]: (qr[0] or qr[1]<0)
... and (qr.__setslice_ _(0,2,divmod(qr[0],N)) or digits[qr[1]]), False))
...


My best shot so far (unless I goofed ;-):
def number_in_base( x, N=10, digits='0123456 789ABCDEF'): ... return '-'[:x<0]+''.join([digits[r] for x in [[abs(x)]]
... for x[0],r in iter(lambda:div mod(x[0], N), (0,0))][::-1]) or '0'
... number_in_base( 126, 2) '1111110' number_in_base(-126, 2) '-1111110' number_in_base(-126, 8) '-176' number_in_base(-126,16) '-7E' number_in_base( 1,16) '1' number_in_base( 1, 2) '1' number_in_base( 0, 2)

'0'

Regards,
Bengt Richter
Jul 18 '05 #11
On Sat, 30 Oct 2004 09:02:14 GMT, bo**@oz.net (Bengt Richter) wrote:
[... previous versions ...]

Silly last best shot put the quotient in an unneeded box. Sorry for all the
self-followups. I think I'll call this my best version (so far ;-):
def number_in_base( x, N=10, digits='0123456 789ABCDEF'): ... return '-'[:x<0]+''.join([digits[r] for q in [abs(x)]
... for q,r in iter(lambda:div mod(q, N), (0,0))][::-1]) or '0'
... number_in_base( 126, 2) '1111110' number_in_base(-126, 2) '-1111110' number_in_base(-126, 8) '-176' number_in_base(-126,16) '-7E' number_in_base( 1,16) '1' number_in_base( 1, 2) '1' number_in_base( 0, 2)

'0'

Regards,
Bengt Richter
Jul 18 '05 #12
On Sun, 31 Oct 2004 03:11:07 GMT, bo**@oz.net (Bengt Richter) wrote:
[...]
Goofed ;-/

def number_in_base( x, N=10, digits='0123456 789ABCDEF'):
return '-'[:x<0]+''.join([digits[r] for q in [abs(x)]
for q,r in iter(lambda:div mod(q, N), (0,0))][::-1]) or digits[0]

(Shouldn't have hardwired '0' in place of digits[0])

It must be time to eat ... sorry.

Regards,
Bengt Richter
Jul 18 '05 #13
On Sat, 30 Oct 2004 16:06:04 -0400, Brian van den Broek
<bv****@po-box.mcgill.ca> wrote:
Hi all,

warning: off topic nitpicking below!

Jeremy Bowers said unto the world upon 2004-10-30 13:29:
On Sat, 30 Oct 2004 12:12:36 +0000, Andrea Griffini wrote:
You can't count using base 1 with positional systems.

Well, you can, sort of. You end up with the integers, obviously, and the
result has a rather striking resemblance to the modern foundations of
number theory, in which there is only one number, 0, and the "increment"
function which returns a number one larger. If you want three, it is
expressed increment(incre ment(increment( 0))), which is rather similar to
the base-1 number "111".


I take it you didn't mean 0 was the only number, but rather the only
primitive number. (Alternatively " '0' is the only individual constant"
in the cant I prefer.)

I am also surprised to see "increment" -- I come to that material with
working in Philosophy of Mathematics and Logic, but almost every
presentation I have ever seen uses "successor" . (I'm going off of
philosophica l and mathematical logic presentations.)


Also the representation used in that context is normally
"0,s0,ss0" or a similar one; anyway using TWO symbols.

In math, or anywhere you need precision, it's important
to weight the words; I said "positional " and normally the
unary counting method is not considered "positional ".
There are a lot of methods for representing numbers, both
historically used (roman, for example) or just theorically
possible. When the word "base" is used the assumption is a
positional system; and 1 cannot be used as base in a
positional system. More to the point the objection that
the code that Alex wrote didn't handle "unary" counting
is IMO quite pointless as that counting system is not
more related to the positional than the ancient roman
counting system.

Of course anyone can give the the words whatever meaning,
it just gets harder to communicate.

Also, if ones really wants to support another different
number representation system after a generic positional
I would prefer the roman one, that's still used nowdays.

Andrea
--
"When I use a word," Humpty Dumpty said, in rather a
scornful tone, "it means just what I choose it to
mean—neither more nor less."
Jul 18 '05 #14
On Fri, 29 Oct 2004 23:58:47 +0200, al*****@yahoo.c om (Alex Martelli) wrote:
I hesitate a bit to post this, but... on the Italian Python NG, somebody
was asking whether there was any way to convert an integer number x into
a string which represents it in an arbitrary base N (given a sequence
with a len of N that gives the digits to use) as "a single expression".

I haven't found a really general way, much less a clear one, but, the
best I have so far is...:

def number_in_base( x, N, digits, maxlen=99):
return '-'[x>=0:] + (
(x and ''.join([digits[k%N] for i in range(maxlen)
for k in [abs(x)//N**i] if k>0])[::-1]
) or digits[0])

Besides the lack of clarity, the obvious defect of this approach is that
darned 'maxlen' parameter -- but then, since I can have only a 'for',
not a 'while', in a list comprehension or generator expression, and I
don't think recursion qualifies as 'a single expression'...:-(

Anyway, improvements and suggestions welcome, thanks!


Not sure if I got filtered out replying to myself, what with an accidental dupe
and all the incremental changes and corrections ;-/ Anyway, I guess you could say
there's a "while" implicit in iter(f, sentinel) that you _can_ do within
a list comprehension ;-)

To sum up, my final version (hope it doesn't still have a bug ;-) was:

def number_in_base( x, N=10, digits='0123456 789ABCDEF'):
return '-'[:x<0]+''.join([digits[r] for q in [abs(x)]
for q,r in iter(lambda:div mod(q, N), (0,0))][::-1]) or digits[0]

BTW, will anything that works in a list comprehension work in a generator expression
(assuming one does not depend on the generator expression having leftover outside
side effect bindings like the LC version)?

Regards,
Bengt Richter
Jul 18 '05 #15
Bengt Richter <bo**@oz.net> wrote:
Not sure if I got filtered out replying to myself, what with an accidental
dupe and all the incremental changes and corrections ;-/ Anyway, I guess
you could say there's a "while" implicit in iter(f, sentinel) that you
_can_ do within a list comprehension ;-)


Yep, excellent suggestion, tx. I went with the logarithm suggestion,
but in other cases the two-arguments iter could surely be the best way
to hide a 'while callable() != sentinel:' in a list comprehension!-)
Alex
Jul 18 '05 #16
Andrea Griffini <ag****@tin.i t> wrote in message news:<nl******* *************** **********@4ax. com>...
On Fri, 29 Oct 2004 23:34:42 GMT, ex*****@divmod. com wrote:
range(maxlen) can be replaced with range(int(math. log(x) / math.log(N)) + 1).


Log accepts the base as second argument.

def number_in_base( x, N=10, digits="0123456 789ABCDEF"):
return '-'[x>=0:]+"".join(
[digits[abs(x)/N**i%N]
for i in xrange(1+int(ma th.log(abs(x)+1 ,N)))
if N**i<=abs(x)][::-1]) or digits[0]
Also, and perhaps you are already aware, number_in_base( x, 1, '0') doesn't produce the correct output with the above algorithm, although I believe it will if you switch to using math.log().


It doesn't handle roman numerals either...


That's easy enough to implement ;-)

roman = lambda n: 'M' * (n // 1000) + ('', 'C', 'C', 'CCC', 'CD', 'D',
'DC', 'DCC', 'DCCC', 'CM')[n // 100 % 10] + ('', 'X', 'XX', 'XXX',
'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC')[n // 10 % 10] + ('', 'I', 'II',
'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX')[n % 10]

I'm sure there's a shorter way, though.
Jul 18 '05 #17
Bengt Richter <bokr <at> oz.net> writes:

BTW, will anything that works in a list comprehension work in a generator
expression (assuming one does not depend on the generator expression having
leftover outside side effect bindings like the LC version)?


Well, I'm not confident enough to say *anything* (though I've used them freely
in my code since 2.4a1 was released and have never had any problems) but they
seem to work for this problem:
def number_in_base( n, b=10, digits='0123456 789ABCDEF'): .... return '-'[:n<0]+''.join(revers ed(list(
.... digits[r]
.... for q in [abs(n)]
.... for q, r in iter(lambda: divmod(q, b), (0, 0))))) or digits[0]
.... number_in_base( 100, 16) '64' number_in_base( 100, 2)

'1100100'

Of course, you don't really gain anything by doing this with a generator
expression since you have to reverse the list.

In Python 3000, the list(genexp) syntax will be exactly equivalent to a list
comprehension[1], at which point, it won't matter. ;)

Steve

[1] http://www.python.org/peps/pep-3000.html#core-language

Jul 18 '05 #18
On 31 Oct 2004 21:12:49 -0800, da*****@yahoo.c om (Dan Bishop) wrote:
roman = lambda n: 'M' * (n // 1000) + ('', 'C', 'C', 'CCC', 'CD', 'D',
'DC', 'DCC', 'DCCC', 'CM')[n // 100 % 10] + ('', 'X', 'XX', 'XXX',
'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC')[n // 10 % 10] + ('', 'I', 'II',
'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX')[n % 10]

I'm sure there's a shorter way, though.


This is a bit shorter ...

roman = lambda x: "".join(["".join(map(lam bda c: "IVXLCDM"[ord(c) -
ord("A")+2*N], "/A/AA/AAA/AB/B/BA/BAA/BAAA/AC".split("/")[x//10**N %
10])) for N in (3, 2, 1, 0)])

Andrea
Jul 18 '05 #19
On Mon, 01 Nov 2004 07:21:09 GMT, Andrea Griffini <ag****@tin.i t>
wrote:
This is a bit shorter ...

roman = lambda x: "".join(["".join(map(lam bda c: "IVXLCDM"[ord(c) -
ord("A")+2*N], "/A/AA/AAA/AB/B/BA/BAA/BAAA/AC".split("/")[x//10**N %
10])) for N in (3, 2, 1, 0)])


No idea why I initially thougt about using ASCII codes... this
is simpler and shorter...

roman = lambda x: "".join(["".join(map(lam bda c: "IVXLCDM"[int(c)
+2*N],"/0/00/000/01/1/10/100/1000/02".split("/")[x//10**N % 10]))
for N in (3, 2, 1, 0)])

Andrea

Jul 18 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
2670
by: Boštjan Jerko | last post by:
Hello ! I need to know if the result of math formula is nan (Not a number). How can I do that? Thanks, B.
2
1397
by: Gianluca_Venezia | last post by:
Talking about high number of record seem ridiculus, if this number is about 88.000 but when I open a form, linked via ODBC to a MYSQL table, the open and the use of that form is slow, and very slow if the form has combo controls. I have a order form, and a combo control for custemer codes. Order table counts 88.000 records, customer tables has 1.500 records.
0
1437
by: gahagan | last post by:
If you encounter this error, most likely one of the controls you're trying to cut/paste is a combo box with a longer-than-average 'Row Source' value. That, apparently, is the problem. Shorter Row Source values don't seem to be a problem. (I don't have time to figure out at what length the error triggers.) Workaround: Remove the Row Source (you can cut/paste the text somewhere else), then try cutting/pasting the control(s) again. Then...
13
3253
by: Fao | last post by:
Hello, I am having some problems with inheritance. The compiler does not not return any error messages, but when I execute the program, it only allows me to enter the number, but nothing else happend. I think the problem may be in my input function or in the main function. If anyone out there can help me it woul be greatly appreciated. Here is the code: #include <iostream>
3
1549
by: Nevyn | last post by:
How do I do that? Turning the layout from the customerID-number "10205" into looking like "10 205"? I've just incresed it from four digits to five, and it looks like this: lsvItem.SubItems(1) = Right("0000" & CStr(rs!customerID), 5), but how do I affect the layout?
4
5747
by: zensunni | last post by:
Here's what my code looks like: ======================================= Set RS = Server.CreateObject("ADODB.Recordset") RS.Open "Table", objConn, 1, 3, 2 If Len(Request.Form("AreaID1")) > 0 Then RS("AreaID1") = Request.Form("AreaID1") End If If Len(Request.Form("AreaID2")) > 0 Then
2
19333
by: mktselvan | last post by:
Hi, Existing running oracle application 11i (11.5.8) Database version is 8.1.7.4 There is any command / way to know the number of concurrent users for this application. select SESSIONS_MAX, SESSIONS_WARNING,
4
2036
by: ravi | last post by:
Hi all, I written and compiled a c++ program using g++ no errors or warning are reported. But when I run it , reporting an error : ERROR: Wrong magic number. What is the reason for this error? anybody had an idea ?
4
2659
by: ajmastrean | last post by:
I cannot get any (hex) number in the "0x80"-"0x89" range (inclusive) to write properly to a file. Any number in this range magically transforms itself into "0x3F". For instance, debugging shows that "0x83" = UInt16 "131" and that converts to Char (curly) "f". Any information would be helpful. String hexNum = { "79", "80", "89", "90" }; System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(@"C: \test.dbf", true,...
6
19190
by: nickyazura | last post by:
hello, i would like to know how to do numbering format for "0000" where each time it will generate 0001,0002,0003 and so on untill 9999. counter = "0000" counter = counter + 1
0
9171
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9032
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8905
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8880
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7743
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5869
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4373
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4625
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2008
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.