Python Forum
Thread Rating:
  • 1 Vote(s) - 2 Average
  • 1
  • 2
  • 3
  • 4
  • 5
function intx()
#1
file intx.py (or seen below) is the function i wrote to extend int() by interpreting digits by s base indicated by the prefix given in the string (argument 1 or only argument).  the module in the intx.py file that includes the function also includes a small command the passes each command line argument to the intx() function and outputs (in decimal) the resultant int that intx() returns.  these are the prefixes available and the base they signify.  they can be given with, or without a leading '0', and in upper or lower case.

              no prefix: {10} decimal
              prefix '0x' or 'x': {16} cetal (hexadecimal)
              prefix '0o' or 'o': {8}  octal
              prefix '0b' or 'b': {2}  binary
              prefix '0t' or 't': {3}  trinary
              prefix '0q' or 'q': {4}  quartic
              prefix '0y' or 'y': {32} duotridecimal
              prefix         ':': {36} hexatridecimal


note that : (hexatridecimal, base 36) is the one exception for a leading 0.  it cannot have one.  i don't remember why i had that restriction in my first implementation (in S/370 assembler) but i am keeping it, for now.  i may change things (expand, keeping compatibility) in the near future.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import division, generators, print_function, with_statement
"""
file          intx.py

purpose       implement a function to do extended conversion of digits to
              integers in various bases.

syntax        value = intx( digits, bases )

digits        all decimal, basic conversion like int()

              letters in the following forms may given in lower or upper
              case or a mix of these:

              no prefix: {10} decimal
              prefix '0x' or 'x': {16} cetal (hexadecimal)
              prefix '0o' or 'o': {8}  octal
              prefix '0b' or 'b': {2}  binary
              prefix '0t' or 't': {3}  trinary
              prefix '0q' or 'q': {4}  quartic
              prefix '0y' or 'y': {32} duotridecimal
              prefix         ':': {36} hexatridecimal

bases         a set of bases allowed for conversion and/or various option
              flags

              10, 16, 8, 2, 3, 4, 32, 36:  enable these bases

              0:   suppress exceptions during conversion
                   (if an exception is suppressed, return None)

              -1:  enable a prefix of '-' negates the number

              -2:  forces the number to be negated

              -8:  interpret a leading '0' as octal

defaults      if no digits are given, return False

              if no bases are given, use the following set for bases:
              { -8, -1, 0, 1, 2, 3, 4, 8, 10, 16, 32, 36 }

author        Phil D. Howard
email         10054452614123394844460370234029112340408691

Please report failures or code improvement to the author.
"""

__license__ = """
Copyright © 2017, by Phil D. Howard - all other rights reserved

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

The author may be contacted using the short first name, middle initial,
and last name, separated by periods, with gmail dot com as the host part
of an email address.
"""

from sys import argv, stderr, stdin, stdout, version_info
default_bases = { -8, -1, 0, 1, 2, 3, 4, 8, 10, 16, 32, 36 }

#-----------------------------------------------------------------------------
octal = {'','0','1','2','3','4','5','6','7'}
#-----------------------------------------------------------------------------
def intx(*a):
    "Convert digits to int, in an extended way, better than int()"

    b = default_bases
    if len(a) > 1:
        b = set(a[1])

    # i bet you do not understand this:
    d = a[0].lower()
    if bytes == str:
        d = ''.join([chr(c) for c in bytearray(d)])
    elif isinstance(d,(bytes,bytearray)):
        d = ''.join([chr(c) for c in bytearray(d)])

    if 0 in b:
        try:
            return intx(d,b-{0})
        except ValueError:
            return None

    if -1 in b and d[:1]=='-':
        return -intx(d[:1],b-{-1})

    if -2 in b:
        return -intx(d,b-{-2})

# the order of the next 7 does not matter, but is arranged by probability

    if 16 in b:
        if d[:2]=='0x':
            return int(d[2:],16)
        if d[:1]=='x':
            return int(d[1:],16)

    if 8 in b:
        if d[:2]=='0o':
            return int(d[2:],8)
        if d[:1]=='o':
            return int(d[1:],8)

    if 2 in b:
        if d[:2]=='0b':
            return int(d[2:],2)
        if d[:1]=='b':
            return int(d[1:],2)

    if 3 in b:
        if d[:2]=='0t':
            return int(d[2:],3)
        if d[:1]=='t':
            return int(d[1:],3)

    if 4 in b:
        if d[:2]=='0q':
            return int(d[2:],4)
        if d[:1]=='q':
            return int(d[1:],4)

    if 32 in b:
        if d[:2]=='0y':
            return int(d[2:],32)
        if d[:1]=='y':
            return int(d[1:],32)

    if 36 in b:
        if d[:1]==':':
            return int(d[1:],36)

    if -8 in b:
        if d[:1]=='0':
            if d[1:2] in octal:
                return int(d[1:],8)

    if 10 in b:
        return int(d,10)

    return None


#-----------------------------------------------------------------------------
def main(args):
    args.pop(0)
    while args:
        arg = args.pop(0)
        i = intx(arg)
        print(repr(arg),'->',repr(i))

    return i


#-----------------------------------------------------------------------------
if __name__ == '__main__':
    try:
        result=main(argv)
        stdout.flush()
    except BrokenPipeError:
        result = 99
    except KeyboardInterrupt:
        print('')
        result = 98
    if result is 0 or result is None or result is True:
        exit(0)
    if result is 1 or result is False:
        exit(1)
    if isinstance(result,str):
        print(result,file=stderr)
        exit(2)
    try:
        exit(int(result))
    except ValueError:
        print(str(result),file=stderr)
        exit(3)
    except TypeError:
        exit(4)
# EOF
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
Without samples it is difficult to use your library.

Meanwhile this works.

#!/usr/bin/python3
import intx

print( intx.intx("0x10") ) # ==> 16
print( intx.intx("0y10") ) # ==> 32

What does the second parameter do ?
intx(digits, bases)
Reply
#3
the 2nd argument is described in source lines 26 to 38 inclusive.  you can provide a set or frozenset or tuple or list ... anything that set() will convert to a set.  0 and negative numbers in the set have special meanings.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
Thanks, I will read it.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020