Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Range between two tuples of integers?

Tuples seem ideal for version-number comparisons (assuming only numeric elements, which is a given in my case). I have two version numbers in the form of tuples comprised of integers. Say those tuples are:

minver = (1,2,3)
maxver = (1,2,9)

is there a simple and elegant way to get the "range" from minver to maxver as a list? I.e. for the above case I would like to get a list like this:

[(1,2,3), (1,2,4), (1,2,5), (1,2,6), (1,2,7), (1,2,8), (1,2,9)]

(Note: it is also fine if the last element is missing from the list, i.e. if the returned range does not include the maximum value.)

The range function clearly does not work (expects integers), but I also don't want to rely on the tuples being exactly x elements (x = 3 in the above case).

For example if I have a minver tuple (1,) it should be treated like (1,0,0) if the maxver tuple contains three values/elements (such as (1,2,3)).

Any way of doing this in a pythonic way (that is elegant)?

like image 451
0xC0000022L Avatar asked Jan 18 '26 10:01

0xC0000022L


1 Answers

Okay - it's 2:30am, so the principle is that you fix the maximum length and upper bound of anyone of the versions, then treat that as a base for the number... Convert your start and end to an int to act as a range, then have another function to convert back to tuple... Will need a bit of work, but fairly sound theory...

from itertools import izip_longest, chain

minver = (1, 1, 3)
maxver = (1, 3, 19)

def version_range(start, end):
    start, end = zip(*izip_longest(start, end, fillvalue=0))
    base = max(max(chain(start, end)), 9) + 1
    def _toint(seq, base):
        return sum(base ** n * val for n, val in enumerate(reversed(seq)))
    def _totuple(num, base, length):
        ret = []
        for n in (base ** i for i in reversed(range(length))):
            res, num = divmod(num, n)
            ret.append(res)
        return tuple(ret)
    for se in xrange(_toint(start, base), _toint(end, base) + 1):
        print _totuple(se, base, len(start))


version_range(minver, maxver)
like image 81
Jon Clements Avatar answered Jan 21 '26 05:01

Jon Clements



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!