diff --git a/banana/bananalib.py b/banana/bananalib.py index 21dc175..55639d3 100644 --- a/banana/bananalib.py +++ b/banana/bananalib.py @@ -1,109 +1,84 @@ """Main module.""" -def encoder(num, dictstart=0, shiftend=0, minlength=0, dictionary=None): - if dictionary is None: - dictionary = [list("bcdfglmnprstvz"), list("aeiou")] +class Codec: + def __init__(self, dictstart=0, shiftend=0, minlength=0, dictionary=None): + self.dictstart = dictstart + self.shiftend = shiftend + if dictionary is None: + self.dictionary = [list("bcdfglmnprstvz"), list("aeiou")] + else: + self.dictionary = dictionary - numdict = len(dictionary) - v = num - st = "" - length = 0 + def encode(self, num, minlength=0): + dictionary = self.dictionary + numdict = len(dictionary) + v = num + st = "" + length = 0 - idx = (numdict - 1 + dictstart + shiftend) % numdict - while not ( - v == 0 and idx == (numdict - 1 + dictstart) % numdict and length >= minlength - ): - r = v % len(dictionary[idx]) - v = int(v / len(dictionary[idx])) - st = dictionary[idx][r] + st - idx = (idx - 1) % numdict - length += 1 + idx = (numdict - 1 + self.dictstart + self.shiftend) % numdict + while not ( + v == 0 + and idx == (numdict - 1 + self.dictstart) % numdict + and length >= minlength + ): + r = v % len(dictionary[idx]) + v = int(v / len(dictionary[idx])) + st = dictionary[idx][r] + st + idx = (idx - 1) % numdict + length += 1 - return st + return st + def decode(self, word): + dictionary = self.dictionary -def decoder(banana, dictstart=0, shiftend=0, dictionary=None): - # defaults - if dictionary is None: - dictionary = [list("bcdfglmnprstvz"), list("aeiou")] # , list("123456") + numdict = len(dictionary) + if (len(word) - self.shiftend) % numdict != 0: + raise ValueError("Banana non valida") + v = 0 + for i in range(len(word)): + r = (numdict + i + self.dictstart) % numdict + try: + v = v * len(dictionary[r]) + dictionary[r].index(word[i]) + except (ValueError, KeyError): + raise ValueError("Carattere non valido in posizione %d" % i + 1) - numdict = len(dictionary) - if (len(banana) - shiftend) % numdict != 0: - raise ValueError("Banana non valida") - v = 0 - for i in range(len(banana)): - r = (numdict + i + dictstart) % numdict - try: - v = v * len(dictionary[r]) + dictionary[r].index(banana[i]) - except (ValueError, KeyError): - raise ValueError("Carattere non valido in posizione %d" % i + 1) + return v - return v + def is_valid(self, word): + dictionary = self.dictionary - -def is_valid(banana, dictstart=0, shiftend=0, dictionary=None): - # defaults - if dictionary is None: - dictionary = [list("bcdfglmnprstvz"), list("aeiou")] # , list("123456") - - numdict = len(dictionary) - if (len(banana) - shiftend) % numdict != 0: - return False - for i in range(len(banana)): - r = (numdict + i + dictstart) % numdict - if banana[i] not in dictionary[r]: + numdict = len(dictionary) + if (len(word) - self.shiftend) % numdict != 0: return False + for i in range(len(word)): + r = (numdict + i + self.dictstart) % numdict + if word[i] not in dictionary[r]: + return False - return True + return True -def banana2dec(word): - return decoder(word) +class BananaCodec(Codec): + def __init__(self): + super().__init__() -def dec2banana(word): - return encoder(word) +class RibesCodec(Codec): + def __init__(self): + super().__init__(0, 1) -def isbanana(word): - return is_valid(word) +class AnanasCodec(Codec): + def __init__(self): + super().__init__(1, 0) -def ribes2dec(word): - return decoder(word, 0, 1) - - -def dec2ribes(word): - return encoder(word, 0, 1) - - -def isribes(word): - return is_valid(word, 0, 1) - - -def avocado2dec(word): - return decoder(word, 1, 1) - - -def dec2avocado(word): - return encoder(word, 1, 1) - - -def isavocado(word): - return is_valid(word, 1, 1) - - -def ananas2dec(word): - return decoder(word, 1, 0) - - -def dec2ananas(word): - return encoder(word, 1, 0) - - -def isananas(word): - return is_valid(word, 1, 0) +class AvocadoCodec(Codec): + def __init__(self): + super().__init__(1, 1) def bananarandom(dictstart=0, shiftend=0, minlength=6, dictionary=None): diff --git a/banana/cli.py b/banana/cli.py index c5666ec..2362868 100644 --- a/banana/cli.py +++ b/banana/cli.py @@ -2,7 +2,76 @@ import argparse import sys -from . import bananalib as banana +import banana + + +def get_codec(args): + if args.banana: + return banana.BananaCodec() + if args.ananas: + return banana.AnanasCodec() + kwargs = {} + if args.dictionary: + kwargs["dictionary"] = args.dictionary + if args.dictstart: + kwargs["dictstart"] = args.dictstart + if args.shiftend: + kwargs["shiftend"] = args.shiftend + print(kwargs) + return banana.Codec(**kwargs) + + +def main_encode(args): + print(get_codec(args).encode(args.num)) + + +def main_decode(args): + print(get_codec(args).decode(args.word)) + + +def main_check(args): + if get_codec(args).is_valid(args.word): + if not args.quiet: + print("yes") + sys.exit(0) + else: + if not args.quiet: + print("no") + sys.exit(1) + + +def main(): + parser = argparse.ArgumentParser(description="Convert dec number to banana") + parser.add_argument("--ananas", action="store_true") + parser.add_argument("--avocado", action="store_true") + parser.add_argument("--banana", action="store_true") + parser.add_argument("--ribes", action="store_true") + parser.add_argument("--dictionary", help="Set dictionary", type=list, nargs="+") + parser.add_argument( + "--dictstart", help="Set starting dictionary", type=int, default=0 + ) + parser.add_argument( + "--shiftend", help="Set shift for ending dictionary", type=int, default=0 + ) + sub = parser.add_subparsers() + encode = sub.add_parser("encode", help="Convert numbers to words") + encode.add_argument("num", type=int) + encode.set_defaults(func=main_encode) + + decode = sub.add_parser("decode", help="Convert words to numbers") + decode.add_argument("word") + decode.set_defaults(func=main_decode) + + check = sub.add_parser("check", help="Convert words to numbers") + check.add_argument("word") + check.add_argument("--quiet", "-q", action="store_true") + check.set_defaults(func=main_check) + + args = parser.parse_args() + if not hasattr(args, "func"): + print("metti un sottocomando!") + sys.exit(1) + args.func(args) def ananas2dec(): @@ -78,7 +147,7 @@ def dec2avocado(): parser.add_argument("--minlength", help="Set minimum length", type=int, default=0) args = parser.parse_args() - print(banana.dec2avocado(args.num)) + print(banana.dec2avocado(args.num, minlength=args.minlength)) def dec2banana(): @@ -121,10 +190,6 @@ def isbanana(): print(banana.isbanana(args.banana)) -def main(): - sys.exit(bananarandom()) - - if __name__ == "__main__": # pragma: no cover main() diff --git a/tests/test_banana.py b/tests/test_banana.py index ae406c9..1cd0531 100644 --- a/tests/test_banana.py +++ b/tests/test_banana.py @@ -3,9 +3,7 @@ """Tests for `banana` package.""" import pytest -from banana import (ananas2dec, avocado2dec, banana2dec, dec2ananas, - dec2avocado, dec2banana, dec2ribes, isananas, isavocado, - isbanana, isribes, ribes2dec) +from banana import AnanasCodec, AvocadoCodec, BananaCodec, RibesCodec banana_conversions = {"be": 1, "beba": 70, "zu": 69, "bezu": 139, "nana": 2485} @@ -74,6 +72,12 @@ ananas_conversions = { } +ananas_codec = AnanasCodec() +avocado_codec = AvocadoCodec() +banana_codec = BananaCodec() +ribes_codec = RibesCodec() + + @pytest.fixture(params=ananas_conversions.items()) def ananas_known(request): yield request.param @@ -81,92 +85,92 @@ def ananas_known(request): def test_banana_to_dec_known(banana_known): word, value = banana_known - assert banana2dec(word) == value + assert banana_codec.decode(word) == value def test_dec_to_banana_known(banana_known): word, value = banana_known - assert dec2banana(value) == word + assert banana_codec.encode(value) == word def test_banana_is_banana(banana_known): - assert isbanana(banana_known[0]) + assert banana_codec.is_valid(banana_known[0]) def test_banana_is_only_banana(banana_known): - assert not isribes(banana_known[0]) - assert not isananas(banana_known[0]) - assert not isavocado(banana_known[0]) + assert not ribes_codec.is_valid(banana_known[0]) + assert not ananas_codec.is_valid(banana_known[0]) + assert not avocado_codec.is_valid(banana_known[0]) def test_banana2dec_prefix_ba(banana_known): """un ba all'inizio non cambia nulla!""" word, value = banana_known for prefix in ("ba", "baba", "bababa"): - assert banana2dec(prefix + word) == value + assert banana_codec.decode(prefix + word) == value def test_ribes_to_dec_known(ribes_known): word, value = ribes_known - assert ribes2dec(word) == value + assert ribes_codec.decode(word) == value def test_dec_to_ribes_known(ribes_known): word, value = ribes_known - assert dec2ribes(value) == word + assert ribes_codec.encode(value) == word def test_ribes_is_ribes(ribes_known): - assert isribes(ribes_known[0]) + assert ribes_codec.is_valid(ribes_known[0]) def test_ribes_is_only_ribes(ribes_known): - assert not isbanana(ribes_known[0]) - assert not isananas(ribes_known[0]) - assert not isavocado(ribes_known[0]) + assert not banana_codec.is_valid(ribes_known[0]) + assert not ananas_codec.is_valid(ribes_known[0]) + assert not avocado_codec.is_valid(ribes_known[0]) def test_avocado_to_dec_known(avocado_known): word, value = avocado_known - assert avocado2dec(word) == value + assert avocado_codec.decode(word) == value def test_dec_to_avocado_known(avocado_known): word, value = avocado_known - assert dec2avocado(value) == word + assert avocado_codec.encode(value) == word def test_avocado_is_avocado(avocado_known): - assert isavocado(avocado_known[0]) + assert avocado_codec.is_valid(avocado_known[0]) def test_avocado_is_only_avocado(avocado_known): - assert not isribes(avocado_known[0]) - assert not isananas(avocado_known[0]) - assert not isbanana(avocado_known[0]) + assert not ribes_codec.is_valid(avocado_known[0]) + assert not ananas_codec.is_valid(avocado_known[0]) + assert not banana_codec.is_valid(avocado_known[0]) def test_ananas_to_dec_known(ananas_known): word, value = ananas_known - assert ananas2dec(word) == value + assert ananas_codec.decode(word) == value def test_dec_to_ananas_known(ananas_known): word, value = ananas_known - assert dec2ananas(value) == word + assert ananas_codec.encode(value) == word def test_ananas_is_ananas(ananas_known): - assert isananas(ananas_known[0]) + assert ananas_codec.is_valid(ananas_known[0]) def test_ananas_is_only_ananas(ananas_known): - assert not isribes(ananas_known[0]) - assert not isbanana(ananas_known[0]) - assert not isbanana(ananas_known[0]) + assert not ribes_codec.is_valid(ananas_known[0]) + assert not banana_codec.is_valid(ananas_known[0]) + assert not banana_codec.is_valid(ananas_known[0]) def test_answer_to_life_the_universe_and_everything(): - banana = banana2dec("banana") + banana = banana_codec.decode("banana") assert banana != 42 assert banana == 2485