From d9dbf0fb8d62738c6c9e3fe2382686d23f0a833d Mon Sep 17 00:00:00 2001 From: "Alexander \"Arav\" Andreev" Date: Fri, 27 Mar 2020 20:14:22 +0400 Subject: [PATCH] Performed some refactoring on an existing code base before further work. --- .gitignore | 2 +- piggybank/cli/__init__.py | 13 ++++++++++++- piggybank/cli/put.py | 15 +++++++++++---- piggybank/cli/show.py | 8 +++++--- piggybank/cli/take.py | 21 ++++++++++++++------- piggybank/currencies.py | 20 +++++++++++--------- piggybank/piggybank.py | 12 ++++-------- piggybank/transaction.py | 9 +++++---- piggybank/util.py | 34 ---------------------------------- 9 files changed, 63 insertions(+), 71 deletions(-) delete mode 100644 piggybank/util.py diff --git a/.gitignore b/.gitignore index a4b1220..50cc661 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ .vscode/ build/ dist/ -piggybank.egg-info/ +*.egg-info/ __pycache__ *.pb diff --git a/piggybank/cli/__init__.py b/piggybank/cli/__init__.py index f903e10..93b5dd1 100644 --- a/piggybank/cli/__init__.py +++ b/piggybank/cli/__init__.py @@ -1,2 +1,13 @@ +from typing import List + +from piggybank.currencies import CURRENCIES + EPILOGUE = """This program is to assist you to keep track of how much coins -you have across your piggy banks.""" \ No newline at end of file +you have across your piggy banks.""" + + +def complement_array_of_coins(coins: List[int], currency: str, + _reversed: bool = False) -> List[int]: + """Complements array of coins up to the count of currency's coins.""" + offset_array = [0] * (CURRENCIES[currency]["count"] - len(coins)) + return offset_array + coins if not _reversed else coins + offset_array \ No newline at end of file diff --git a/piggybank/cli/put.py b/piggybank/cli/put.py index 4463d5c..3e750a5 100644 --- a/piggybank/cli/put.py +++ b/piggybank/cli/put.py @@ -5,12 +5,10 @@ from os.path import exists from sys import exit, stderr from piggybank import print_program_version -from piggybank.cli import EPILOGUE +from piggybank.cli import EPILOGUE, complement_array_of_coins from piggybank.currencies import CURRENCIES, DEFAULT_CURRENCY, \ BaseCurrencyError, print_supported_currencies from piggybank.piggybank import PiggyBank -from piggybank.util import add_common_arguments_to_parser, \ - complement_array_of_coins __all__ = ["main"] @@ -31,7 +29,16 @@ def main() -> None: help="set currency of a piggy bank. Not applicable to" "an existing one") - add_common_arguments_to_parser(parser) + parser.add_argument("-v", "--version", action="store_true", + help="show program's version and license and exit") + parser.add_argument("--list-currencies", action="store_true", + help="list all supported currencies and exit") + + parser.add_argument("-r", "--reverse", action="store_true", + help="reverse a set of coins so incomplete set" + "fills with zeros from right. E.g. '8 9' will be" + "interpreted as '8 9 0 0 0 0' instead of" + "'0 0 0 0 8 9'") args = parser.parse_args() diff --git a/piggybank/cli/show.py b/piggybank/cli/show.py index 1393105..98b7dfe 100644 --- a/piggybank/cli/show.py +++ b/piggybank/cli/show.py @@ -1,4 +1,4 @@ -"""CLI: Take a set of coins from a piggy bank.""" +"""CLI: Show summarised information on a piggybank.""" from argparse import ArgumentParser from os.path import exists @@ -9,7 +9,6 @@ from piggybank.cli import EPILOGUE from piggybank.currencies import CURRENCIES, DEFAULT_CURRENCY, \ BaseCurrencyError, print_supported_currencies from piggybank.piggybank import PiggyBank -from piggybank.util import add_common_arguments_to_parser __all__ = ["main"] @@ -88,7 +87,10 @@ def main(): help="merge multiple files to show how much do you" "have across them. They all should be of same currency") - add_common_arguments_to_parser(parser, include_reverse_flag=False) + parser.add_argument("-v", "--version", action="store_true", + help="show program's version and license and exit") + parser.add_argument("--list-currencies", action="store_true", + help="list all supported currencies and exit") args = parser.parse_args() diff --git a/piggybank/cli/take.py b/piggybank/cli/take.py index 0e12432..3dbddea 100644 --- a/piggybank/cli/take.py +++ b/piggybank/cli/take.py @@ -4,13 +4,11 @@ from argparse import ArgumentParser from sys import exit, stderr from piggybank import print_program_version -from piggybank.cli import EPILOGUE +from piggybank.cli import EPILOGUE, complement_array_of_coins from piggybank.currencies import CURRENCIES, DEFAULT_CURRENCY, \ BaseCurrencyError, print_supported_currencies from piggybank.piggybank import PiggyBank from piggybank.transaction import TYPE_OUTCOME -from piggybank.util import add_common_arguments_to_parser, \ - complement_array_of_coins __all__ = ["main"] @@ -18,16 +16,25 @@ __all__ = ["main"] def main(): """An entry point for a take command.""" parser = ArgumentParser(prog="piggybank-take", - description="Take a set of coins from a coin box.", + description="Take a set of coins from a piggy bank.", epilog=EPILOGUE) parser.add_argument("file", type=str, - help="a coin box file name. Missing .cb extension will" - "be added") + help="a piggy bank file name. Missing .pb extension" + "will be added") parser.add_argument("coins", type=int, nargs="+", metavar="COIN", help="add a set of coins. A new file will be created" "if it doesn't exist") - add_common_arguments_to_parser(parser) + parser.add_argument("-v", "--version", action="store_true", + help="show program's version and license and exit") + parser.add_argument("--list-currencies", action="store_true", + help="list all supported currencies and exit") + + parser.add_argument("-r", "--reverse", action="store_true", + help="reverse a set of coins so incomplete set" + "fills with zeros from right. E.g. '8 9' will be" + "interpreted as '8 9 0 0 0 0' instead of" + "'0 0 0 0 8 9'") args = parser.parse_args() diff --git a/piggybank/currencies.py b/piggybank/currencies.py index c5ff68b..be66164 100644 --- a/piggybank/currencies.py +++ b/piggybank/currencies.py @@ -1,20 +1,22 @@ """Here is a dictionary of supported currencies defined. Which could be easily extended with new ones. -Each dictionary entry has an ISO code of a currency as its key. Or it can -slightly differ from an ISO to represent a modified version of a currency. An -example is SRUB entry for shortened version of RUB where coins of 1 and 5 kopek -value were removed. And value is an another dictionary consists of following -fields: +Each entry is a dictionary that has an ISO code of a currency as its key. Or it +can be slightly differ from an ISO code to represent a modified version of a +currency. + +Each entry consists of following fields: name -- a full name of a currency; description -- usually a country where this currency is used is being mentioned. Plus additional information; count -- a number of coins in a currency; names -- an array of names for each coins' face values; - multipliers -- an array of multipliers for each face value in a decimal - format. Decimal is used to avoid problems of rounding float numbers. - So first two digits are used to store a fraction part. You can simply - divide this number by 100 to get a regular floating-point number. + multipliers -- an array of multipliers for each face value in a decimal* + format. + +* - Decimal is used to avoid problems of rounding float numbers. So first two +digits to the right are used to store a fraction part. You can simply divide +this number by 100 to get a regular floating-point number. """ from typing import Dict, List, TypedDict diff --git a/piggybank/piggybank.py b/piggybank/piggybank.py index a059b5f..1799815 100644 --- a/piggybank/piggybank.py +++ b/piggybank/piggybank.py @@ -1,4 +1,4 @@ -"""Implementation of the piggy bank itself.""" +"""PiggyBank implementation.""" from __future__ import annotations from os.path import exists @@ -14,8 +14,7 @@ __all__ = ["PiggyBank"] class PiggyBank: - """This class stores transactions and do file I/O on piggy bank - .pb files.""" + """This class stores array of transactions and perform some actions on it.""" def __init__(self, currency: str = DEFAULT_CURRENCY) -> None: if currency.upper() in CURRENCIES: self._currency = currency.upper() @@ -28,7 +27,7 @@ class PiggyBank: """Make a transaction.""" if len(coins) != CURRENCIES[self.currency]["count"]: raise ValueError("Length of passed coins list doesn't match the " - f"currency's coins count ({len(coins)} " + f"currency's coins count. ({len(coins)} " f"!= {CURRENCIES[self.currency]['count']})") self._transactions.append(Transaction(coins, direction)) @@ -41,7 +40,7 @@ class PiggyBank: @property def count(self) -> List[int]: - """Returns a list of counts for each face value.""" + """Returns a list of counts for each face value in total.""" count = [0] * CURRENCIES[self.currency]["count"] for tr in self.transactions: count = [x + y if tr.direction == TYPE_INCOME @@ -123,6 +122,3 @@ class PiggyBank: new = PiggyBank(self.currency) new._transactions = self.transactions + piggybank._transactions return new - - def __repr__(self) -> str: - return f"PiggyBank(currency={self.currency!r})" diff --git a/piggybank/transaction.py b/piggybank/transaction.py index 25d008c..dc16de0 100644 --- a/piggybank/transaction.py +++ b/piggybank/transaction.py @@ -1,4 +1,4 @@ -"""Implementation of Transaction class.""" +"""Transaction class implementation.""" from __future__ import annotations from time import strftime, strptime, gmtime @@ -12,8 +12,9 @@ TIME_FORMAT = "%Y-%m-%dT%H:%M:%S" class Transaction: - """Represents a single transaction. - Consists of array of coins' list, direction and timestamp.""" + """Transaction consists of a timestamp, a direction + and an array of coins. It doesn't depend on a currency. Only coins count is + stored.""" def __init__(self, coins, direction: str = TYPE_INCOME, timestamp: Optional[str] = None) -> None: self.coins = coins @@ -29,7 +30,7 @@ class Transaction: strptime(timestamp, TIME_FORMAT) except ValueError: raise ValueError(f"Timestamp {timestamp} has wrong format. " - f"The right one is {TIME_FORMAT}") + f"The right one is '{TIME_FORMAT}''") self.timestamp = timestamp @staticmethod diff --git a/piggybank/util.py b/piggybank/util.py deleted file mode 100644 index 6268a5e..0000000 --- a/piggybank/util.py +++ /dev/null @@ -1,34 +0,0 @@ -"""Utility functions.""" - -from argparse import ArgumentParser -from typing import List - -from piggybank import __version__, __copyright__, __license__ -from piggybank.currencies import CURRENCIES, DEFAULT_CURRENCY - - -__all__ = ["add_common_arguments_to_parser", "complement_array_of_coins"] - - -def add_common_arguments_to_parser(parser: ArgumentParser, - include_reverse_flag: bool = True) -> None: - """Extends ArgumentParser with a common set of arguments that are shared - amongst all parsers in CLI module.""" - parser.add_argument("-v", "--version", action="store_true", - help="show program's version and license and exit") - parser.add_argument("--list-currencies", action="store_true", - help="list all supported currencies and exit") - - if include_reverse_flag: - parser.add_argument("-r", "--reverse", action="store_true", - help="reverse a set of coins so incomplete set" - "fills with zeros from right. E.g. '8 9' will be" - "interpreted as '8 9 0 0 0 0' instead of" - "'0 0 0 0 8 9'") - - -def complement_array_of_coins(coins: List[int], currency: str, - _reversed: bool = False) -> List[int]: - """Complements array of coins up to the count of currency's coins.""" - offset_array = [0] * (CURRENCIES[currency]["count"] - len(coins)) - return offset_array + coins if not _reversed else coins + offset_array