Matt23

Number'sBaseConverter

Feb 1st, 2017
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.97 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. """
  3. The program allows user to convert numbers between bases from 2 to 36 by
  4. extending the available characters' set to all 26 letters of English alphabet
  5. 10 digits + 26 letters = 36 characters
  6. """
  7. import argparse
  8.  
  9. __author__ = "El Destornillador"
  10. __copyright__ = "Copyright 2016"
  11. __license__ = "MIT"
  12.  
  13.  
  14. def main():
  15.     arg_parser = argparse.ArgumentParser(description="Converting numbers between bases")
  16.     arg_parser.add_argument('number', type=str.upper, help='the number supposed to be converted')
  17.     arg_parser.add_argument('current_base', type=int, help='base the number is written in')
  18.     arg_parser.add_argument('new_base', type=int, help='base the number will be converted to')
  19.     arg_parser.add_argument('-r', '--raw', action='store_true', help='displays the converted number only')
  20.     arg_parser.add_argument('-c', '--count', action='store_true', help='counts characters in output')
  21.     arg_parser.add_argument('-l', '--length', type=int,
  22.                             help='appends preceding zeros if output is shorter than given number', default=0)
  23.     args = arg_parser.parse_args()
  24.  
  25.     try:
  26.         number = convert_number_to_base(args.number, args.current_base, args.new_base)
  27.     except Exception as e:
  28.         print(e)
  29.         return
  30.  
  31.     # appends preceding zeros to output if requested
  32.     if args.length > len(number):
  33.         count = args.length - len(number)
  34.         number = '0' * count + number
  35.  
  36.     output = number
  37.  
  38.     # adds extended output unless --raw specified
  39.     if not args.raw:
  40.         output = "{}({}) = {}({})".format(args.number, args.current_base, number, args.new_base)
  41.  
  42.  
  43.     # adds number's length to the output if --count specified  
  44.     if args.count:
  45.         output += "  # {} characters".format(len(number))
  46.  
  47.     print(output)
  48.  
  49.  
  50. def convert_number_to_base(number, current_base, new_base):
  51.     characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"  # characters the value can be written with
  52.     decimal_representation = 0
  53.  
  54.     # checking whether given bases are valid
  55.     if current_base not in range(2, len(characters) + 1) or new_base not in range(2, len(characters) + 1):
  56.         raise Exception("The base must be in range from 2 to {}".format(len(characters)))
  57.  
  58.     # converting value to 10 based system and checking its correctness
  59.     for exponent, c in enumerate(number[::-1]):  # enumerating reverted string
  60.         if characters.index(c) >= current_base:
  61.             raise Exception("The number is not written in {} based system".format(current_base))
  62.         decimal_representation += characters.index(c) * current_base ** exponent
  63.  
  64.     # converting number to requested base by doing modulo calculations
  65.     requested_representation = ""
  66.     while decimal_representation >= 1:
  67.         requested_representation += characters[decimal_representation % new_base]
  68.         decimal_representation //= new_base
  69.  
  70.     return requested_representation[::-1]
  71.  
  72.  
  73. if __name__ == '__main__':
  74.     main()
Advertisement
Add Comment
Please, Sign In to add comment