Browse Source

mega refactor con i Codec

boyska 3 years ago
parent
commit
819388ca45
3 changed files with 172 additions and 128 deletions
  1. 68 93
      banana/bananalib.py
  2. 71 6
      banana/cli.py
  3. 33 29
      tests/test_banana.py

+ 68 - 93
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")]
-
-    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
-
-    return st
-
-
-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(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
-
-
-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]:
+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
+
+    def encode(self, num, minlength=0):
+        dictionary = self.dictionary
+        numdict = len(dictionary)
+        v = num
+        st = ""
+        length = 0
+
+        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
+
+    def decode(self, word):
+        dictionary = self.dictionary
+
+        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)
+
+        return v
+
+    def is_valid(self, word):
+        dictionary = self.dictionary
+
+        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
-
-
-def banana2dec(word):
-    return decoder(word)
-
-
-def dec2banana(word):
-    return encoder(word)
-
-
-def isbanana(word):
-    return is_valid(word)
-
-
-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)
+        return True
 
 
-def isavocado(word):
-    return is_valid(word, 1, 1)
+class BananaCodec(Codec):
+    def __init__(self):
+        super().__init__()
 
 
-def ananas2dec(word):
-    return decoder(word, 1, 0)
+class RibesCodec(Codec):
+    def __init__(self):
+        super().__init__(0, 1)
 
 
-def dec2ananas(word):
-    return encoder(word, 1, 0)
+class AnanasCodec(Codec):
+    def __init__(self):
+        super().__init__(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):

+ 71 - 6
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()

+ 33 - 29
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