mega refactor con i Codec

This commit is contained in:
boyska 2020-10-02 11:10:33 +02:00
parent 5d25fd334e
commit 819388ca45
3 changed files with 164 additions and 120 deletions

View file

@ -1,109 +1,84 @@
"""Main module.""" """Main module."""
def encoder(num, dictstart=0, shiftend=0, minlength=0, dictionary=None): class Codec:
if dictionary is None: def __init__(self, dictstart=0, shiftend=0, minlength=0, dictionary=None):
dictionary = [list("bcdfglmnprstvz"), list("aeiou")] self.dictstart = dictstart
self.shiftend = shiftend
if dictionary is None:
self.dictionary = [list("bcdfglmnprstvz"), list("aeiou")]
else:
self.dictionary = dictionary
numdict = len(dictionary) def encode(self, num, minlength=0):
v = num dictionary = self.dictionary
st = "" numdict = len(dictionary)
length = 0 v = num
st = ""
length = 0
idx = (numdict - 1 + dictstart + shiftend) % numdict idx = (numdict - 1 + self.dictstart + self.shiftend) % numdict
while not ( while not (
v == 0 and idx == (numdict - 1 + dictstart) % numdict and length >= minlength v == 0
): and idx == (numdict - 1 + self.dictstart) % numdict
r = v % len(dictionary[idx]) and length >= minlength
v = int(v / len(dictionary[idx])) ):
st = dictionary[idx][r] + st r = v % len(dictionary[idx])
idx = (idx - 1) % numdict v = int(v / len(dictionary[idx]))
length += 1 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): numdict = len(dictionary)
# defaults if (len(word) - self.shiftend) % numdict != 0:
if dictionary is None: raise ValueError("Banana non valida")
dictionary = [list("bcdfglmnprstvz"), list("aeiou")] # , list("123456") 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) return v
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(self, word):
dictionary = self.dictionary
numdict = len(dictionary)
def is_valid(banana, dictstart=0, shiftend=0, dictionary=None): if (len(word) - self.shiftend) % numdict != 0:
# 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]:
return False 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): class BananaCodec(Codec):
return decoder(word) def __init__(self):
super().__init__()
def dec2banana(word): class RibesCodec(Codec):
return encoder(word) def __init__(self):
super().__init__(0, 1)
def isbanana(word): class AnanasCodec(Codec):
return is_valid(word) def __init__(self):
super().__init__(1, 0)
def ribes2dec(word): class AvocadoCodec(Codec):
return decoder(word, 0, 1) def __init__(self):
super().__init__(1, 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)
def bananarandom(dictstart=0, shiftend=0, minlength=6, dictionary=None): def bananarandom(dictstart=0, shiftend=0, minlength=6, dictionary=None):

View file

@ -2,7 +2,76 @@
import argparse import argparse
import sys 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(): def ananas2dec():
@ -78,7 +147,7 @@ def dec2avocado():
parser.add_argument("--minlength", help="Set minimum length", type=int, default=0) parser.add_argument("--minlength", help="Set minimum length", type=int, default=0)
args = parser.parse_args() args = parser.parse_args()
print(banana.dec2avocado(args.num)) print(banana.dec2avocado(args.num, minlength=args.minlength))
def dec2banana(): def dec2banana():
@ -121,10 +190,6 @@ def isbanana():
print(banana.isbanana(args.banana)) print(banana.isbanana(args.banana))
def main():
sys.exit(bananarandom())
if __name__ == "__main__": if __name__ == "__main__":
# pragma: no cover # pragma: no cover
main() main()

View file

@ -3,9 +3,7 @@
"""Tests for `banana` package.""" """Tests for `banana` package."""
import pytest import pytest
from banana import (ananas2dec, avocado2dec, banana2dec, dec2ananas, from banana import AnanasCodec, AvocadoCodec, BananaCodec, RibesCodec
dec2avocado, dec2banana, dec2ribes, isananas, isavocado,
isbanana, isribes, ribes2dec)
banana_conversions = {"be": 1, "beba": 70, "zu": 69, "bezu": 139, "nana": 2485} 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()) @pytest.fixture(params=ananas_conversions.items())
def ananas_known(request): def ananas_known(request):
yield request.param yield request.param
@ -81,92 +85,92 @@ def ananas_known(request):
def test_banana_to_dec_known(banana_known): def test_banana_to_dec_known(banana_known):
word, value = banana_known word, value = banana_known
assert banana2dec(word) == value assert banana_codec.decode(word) == value
def test_dec_to_banana_known(banana_known): def test_dec_to_banana_known(banana_known):
word, value = banana_known word, value = banana_known
assert dec2banana(value) == word assert banana_codec.encode(value) == word
def test_banana_is_banana(banana_known): 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): def test_banana_is_only_banana(banana_known):
assert not isribes(banana_known[0]) assert not ribes_codec.is_valid(banana_known[0])
assert not isananas(banana_known[0]) assert not ananas_codec.is_valid(banana_known[0])
assert not isavocado(banana_known[0]) assert not avocado_codec.is_valid(banana_known[0])
def test_banana2dec_prefix_ba(banana_known): def test_banana2dec_prefix_ba(banana_known):
"""un ba all'inizio non cambia nulla!""" """un ba all'inizio non cambia nulla!"""
word, value = banana_known word, value = banana_known
for prefix in ("ba", "baba", "bababa"): 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): def test_ribes_to_dec_known(ribes_known):
word, value = ribes_known word, value = ribes_known
assert ribes2dec(word) == value assert ribes_codec.decode(word) == value
def test_dec_to_ribes_known(ribes_known): def test_dec_to_ribes_known(ribes_known):
word, value = ribes_known word, value = ribes_known
assert dec2ribes(value) == word assert ribes_codec.encode(value) == word
def test_ribes_is_ribes(ribes_known): 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): def test_ribes_is_only_ribes(ribes_known):
assert not isbanana(ribes_known[0]) assert not banana_codec.is_valid(ribes_known[0])
assert not isananas(ribes_known[0]) assert not ananas_codec.is_valid(ribes_known[0])
assert not isavocado(ribes_known[0]) assert not avocado_codec.is_valid(ribes_known[0])
def test_avocado_to_dec_known(avocado_known): def test_avocado_to_dec_known(avocado_known):
word, value = avocado_known word, value = avocado_known
assert avocado2dec(word) == value assert avocado_codec.decode(word) == value
def test_dec_to_avocado_known(avocado_known): def test_dec_to_avocado_known(avocado_known):
word, value = avocado_known word, value = avocado_known
assert dec2avocado(value) == word assert avocado_codec.encode(value) == word
def test_avocado_is_avocado(avocado_known): 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): def test_avocado_is_only_avocado(avocado_known):
assert not isribes(avocado_known[0]) assert not ribes_codec.is_valid(avocado_known[0])
assert not isananas(avocado_known[0]) assert not ananas_codec.is_valid(avocado_known[0])
assert not isbanana(avocado_known[0]) assert not banana_codec.is_valid(avocado_known[0])
def test_ananas_to_dec_known(ananas_known): def test_ananas_to_dec_known(ananas_known):
word, value = ananas_known word, value = ananas_known
assert ananas2dec(word) == value assert ananas_codec.decode(word) == value
def test_dec_to_ananas_known(ananas_known): def test_dec_to_ananas_known(ananas_known):
word, value = ananas_known word, value = ananas_known
assert dec2ananas(value) == word assert ananas_codec.encode(value) == word
def test_ananas_is_ananas(ananas_known): 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): def test_ananas_is_only_ananas(ananas_known):
assert not isribes(ananas_known[0]) assert not ribes_codec.is_valid(ananas_known[0])
assert not isbanana(ananas_known[0]) assert not banana_codec.is_valid(ananas_known[0])
assert not isbanana(ananas_known[0]) assert not banana_codec.is_valid(ananas_known[0])
def test_answer_to_life_the_universe_and_everything(): def test_answer_to_life_the_universe_and_everything():
banana = banana2dec("banana") banana = banana_codec.decode("banana")
assert banana != 42 assert banana != 42
assert banana == 2485 assert banana == 2485