The little things give you away... A collection of various small helper stuff
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

66 lines
2.1 KiB

  1. #!/usr/bin/env python3
  2. import itertools
  3. import sys
  4. def decimal_to_alphabet(n: int, alphabet: str) -> str:
  5. if n == 0:
  6. return alphabet[0]
  7. base = len(alphabet)
  8. digits = []
  9. while n:
  10. digits.append(alphabet[n % base])
  11. n //= base
  12. return ''.join(digits[::-1])
  13. def alphabet_to_decimal(s: str, alphabet: str) -> int:
  14. base = len(alphabet)
  15. l = len(s)
  16. return sum(alphabet.index(s[l - 1 - i]) * base ** i for i in range(l))
  17. def test():
  18. assert alphabet_to_decimal('ff', '0123456789abcdef') == 255
  19. assert alphabet_to_decimal('100', '0123456789abcdef') == 256
  20. assert decimal_to_alphabet(255, '0123456789abcdef') == 'ff'
  21. assert decimal_to_alphabet(256, '0123456789abcdef') == '100'
  22. assert decimal_to_alphabet(0, '0123456789') == '0'
  23. def convert_start_stop(s, alphabet):
  24. if ':' in s:
  25. valalphabet, value = s.split(':')
  26. if not valalphabet:
  27. valalphabet = '0123456789'
  28. else:
  29. valalphabet, value = alphabet, s
  30. return alphabet_to_decimal(value, valalphabet)
  31. if __name__ == '__main__':
  32. if len(sys.argv) == 2 and sys.argv[1] == '--test':
  33. test()
  34. elif len(sys.argv) in (3, 4):
  35. if len(sys.argv) == 3:
  36. sys.argv.append(sys.argv[-1])
  37. alphabet = sys.argv[1]
  38. start, stop = map(lambda x: convert_start_stop(x, alphabet), sys.argv[2:])
  39. for i in range(start, stop + 1):
  40. try:
  41. sys.stdout.write(decimal_to_alphabet(i, alphabet) + '\n')
  42. except (BrokenPipeError, IOError):
  43. try:
  44. sys.stdout.close()
  45. except IOError:
  46. pass
  47. break
  48. else:
  49. print('Usage: alphabetseq ALPHABET START [STOP]', file = sys.stderr)
  50. print('Generates the sequence from START to STOP (inclusive) using ALPHABET', file = sys.stderr)
  51. print('If STOP is omitted, it defaults to START, effectively making this a simple base transformation', file = sys.stderr)
  52. print('START and STOP have values of the form [[VALALPHABET]:]VALUE.', file = sys.stderr)
  53. print(' In the [VALALPHABET]:VALUE form, VALUE is expressed in terms of VALALPHABET, which defaults to 0123456789 (i.e. decimal) if omitted.', file = sys.stderr)
  54. print(' In the VALUE form, it is converted using ALPHABET.', file = sys.stderr)
  55. sys.exit(1)