Performed some refactoring on an existing code base before further work.
This commit is contained in:
parent
fc15b333b7
commit
d9dbf0fb8d
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,6 @@
|
||||
.vscode/
|
||||
build/
|
||||
dist/
|
||||
piggybank.egg-info/
|
||||
*.egg-info/
|
||||
__pycache__
|
||||
*.pb
|
||||
|
@ -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."""
|
||||
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
|
@ -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()
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
@ -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})"
|
||||
|
@ -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
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user