Final rewrite of CLI arguments form. Now program has single entry point that serves everything. README to be updated.
This commit is contained in:
parent
ab6647ceb3
commit
f4f026f8b2
@ -1,9 +1,9 @@
|
||||
__all__ = ["__date__", "__version__", "__author__", "__author_email__",
|
||||
"__copyright__", "__license__", "PIGGYBANK_FILE_EXTENSION",
|
||||
"print_program_version"]
|
||||
"VERSION"]
|
||||
|
||||
|
||||
__date__ = "6 June 2020"
|
||||
__date__ = "7 June 2020"
|
||||
__version__ = "1.0.0"
|
||||
__author__ = "Alexander \"Arav\" Andreev"
|
||||
__author_email__ = "me@arav.top"
|
||||
@ -17,10 +17,5 @@ http://www.wtfpl.net/ for more details."""
|
||||
|
||||
|
||||
PIGGYBANK_FILE_EXTENSION = ".pb"
|
||||
|
||||
|
||||
def print_program_version() -> None:
|
||||
"""Print information about program. Includes name and version; copyright
|
||||
notice and license."""
|
||||
print(f"PiggyBank ver. {__version__} ({__date__})\n\n{__copyright__}\n"
|
||||
f"\n{__license__}")
|
||||
VERSION = f"PiggyBank ver. {__version__} ({__date__})\n\n{__copyright__}\n" \
|
||||
f"\n{__license__}"
|
||||
|
@ -1,74 +1,12 @@
|
||||
from re import search
|
||||
from typing import List, Callable
|
||||
from sys import argv
|
||||
from typing import List
|
||||
|
||||
from piggybank import print_program_version
|
||||
from piggybank.configuration import Configuration
|
||||
from piggybank.currencies import CURRENCIES
|
||||
|
||||
__all__ = ["handle_default_arguments", "complement_list_of_coins",
|
||||
"print_supported_currencies", "decimal_to_float"]
|
||||
|
||||
|
||||
USAGE_COMMON: str = "Usage: piggybank-* " \
|
||||
"[(-h|--help)|(-v|--version)|(-L|--list-currencies)]\n" \
|
||||
"A set of common flags. Only one could be specified.\n" \
|
||||
"-h, --help -- print this help;\n" \
|
||||
"-v, --version -- print program version;\n" \
|
||||
"-L, --list-currencies -- print supported currencies;\n" \
|
||||
"--set-default-currency CURRENCY -- set default currency.\n"
|
||||
|
||||
|
||||
def parse_common_arguments(args: str):
|
||||
r = r"(?P<help>-h|--help)|(?P<version>-v|--version)" \
|
||||
r"|(?P<list_currencies>-L|--list-currencies)" \
|
||||
r"|(?=--set-default-currency (?P<default_currency>\w+))"
|
||||
argd = search(r, args)
|
||||
if not argd is None:
|
||||
argd = argd.groupdict()
|
||||
return {
|
||||
"help": not argd["help"] is None,
|
||||
"version": not argd["version"] is None,
|
||||
"list-currencies": not argd["list_currencies"] is None,
|
||||
"default-currency": argd["default_currency"] }
|
||||
return None
|
||||
|
||||
|
||||
def handle_default_arguments(args: dict, help_func: Callable) -> None:
|
||||
cargs = parse_common_arguments(' '.join(argv))
|
||||
if not cargs is None:
|
||||
if cargs["help"]:
|
||||
help_func()
|
||||
print(USAGE_COMMON)
|
||||
exit()
|
||||
elif cargs["version"]:
|
||||
print_program_version()
|
||||
exit()
|
||||
elif cargs["list-currencies"]:
|
||||
print_supported_currencies()
|
||||
exit()
|
||||
elif not cargs["default-currency"] is None:
|
||||
conf = Configuration()
|
||||
conf["default-currency"] = cargs["default-currency"]
|
||||
conf.save()
|
||||
exit()
|
||||
|
||||
|
||||
def print_supported_currencies() -> None:
|
||||
"""Print a list of supported currencies."""
|
||||
print("Supported currencies are:")
|
||||
for cur in CURRENCIES:
|
||||
print(f" {cur:^4} ┃ {CURRENCIES[cur]['name']:^31}"
|
||||
f" ┃ {CURRENCIES[cur]['description']}")
|
||||
print("Default currency is", Configuration()["default-currency"])
|
||||
__all__ = ["complement_list_of_coins"]
|
||||
|
||||
|
||||
def complement_list_of_coins(coins: List[int], currency: str,
|
||||
_reversed: bool = False) -> List[int]:
|
||||
"""Complements list of coins up to the count of currency's coins."""
|
||||
offset_array = [0] * (CURRENCIES[currency]["count"] - len(coins))
|
||||
offset_array = [0] * (len(CURRENCIES[currency]) - len(coins))
|
||||
return offset_array + coins if not _reversed else coins + offset_array
|
||||
|
||||
def decimal_to_float(lst: List[int]) -> List[float]:
|
||||
"""Converts decimal style of storing money amounts to float."""
|
||||
return list(map(lambda x: x / 100, lst))
|
||||
|
178
piggybank/cli/main.py
Normal file
178
piggybank/cli/main.py
Normal file
@ -0,0 +1,178 @@
|
||||
"""CLI: main"""
|
||||
|
||||
from re import search, split
|
||||
from sys import argv, stderr
|
||||
|
||||
from piggybank import VERSION
|
||||
from piggybank.cli import complement_list_of_coins
|
||||
from piggybank.configuration import Configuration
|
||||
from piggybank.currencies import Currency, BaseCurrencyError, CURRENCIES
|
||||
from piggybank.piggybank import PiggyBank
|
||||
from piggybank.transaction import sum_transactions, TYPE_INCOME, TYPE_OUTCOME
|
||||
|
||||
__all__ = ["main"]
|
||||
|
||||
|
||||
USAGE = \
|
||||
"""Usage: piggybank [OPTIONS] (COINS in FILE [of CURRENCY] | COINS from FILE
|
||||
| show FILE [with t(ransactions)])
|
||||
|
||||
Options:
|
||||
\t-h,--help -- print this help;
|
||||
\t-v,--version -- print program version;
|
||||
\t-L,--list-currencies -- list supported currencies and a default one;
|
||||
\t--set-default-currency -- set currency that'll be used as a default;
|
||||
\t-r,--reversed -- change COINS' complementation from left to right.
|
||||
\t (e.g. 4 5 -> 0 0 0 0 4 5 by default; 4 5 0 0 0 0
|
||||
\t with this flag. If currency has 6 coins)
|
||||
|
||||
There are three actions available: put, take and show.
|
||||
|
||||
Put: piggybank [-r|--reversed] COINS in FILE [of CURRENCY]
|
||||
Take: piggybank [-r|--reversed] COINS from FILE
|
||||
Show: piggybank show FILE [with t(ransactions)]
|
||||
|
||||
Arguments:
|
||||
\tCOINS -- a set of comma or whitespace separated coin counts;
|
||||
\tFILE -- a filename of a piggybank;
|
||||
\tof CURRENCY -- set a partcular currency for a piggybank;
|
||||
\twith t(ransactions) -- print a table of transactions as well.
|
||||
"""
|
||||
|
||||
|
||||
def parse_common_arguments(args: str) -> dict:
|
||||
r = r"(?P<help>-h|--help)|(?P<version>-v|--version)" \
|
||||
r"|(?P<list_currencies>-L|--list-currencies)" \
|
||||
r"|(?=--set-default-currency (?P<default_currency>\w+))"
|
||||
argd = search(r, args)
|
||||
if not argd is None:
|
||||
argd = argd.groupdict()
|
||||
return {
|
||||
"help": not argd["help"] is None,
|
||||
"version": not argd["version"] is None,
|
||||
"list-currencies": not argd["list_currencies"] is None,
|
||||
"default-currency": argd["default_currency"] }
|
||||
return None
|
||||
|
||||
def parse_arguments(args: str) -> dict:
|
||||
r = r"((?P<reversed>-r|--reversed)? ?(?P<coins>[\d, ]+)?)" \
|
||||
r" ?(?P<action>in|from|show) (?P<file>\S+)" \
|
||||
r" ?(?=(?=of (?P<currency>\S+)" \
|
||||
r"|(?=with (?P<transactions>t|transactions))))?"
|
||||
argd = search(r, args)
|
||||
if not argd is None:
|
||||
argd = argd.groupdict()
|
||||
return {
|
||||
"reversed": not argd["reversed"] is None,
|
||||
"coins": list(map(int, split(r"\D", argd["coins"].strip()))) \
|
||||
if not argd["coins"] is None else None,
|
||||
"action": argd["action"],
|
||||
"file": argd["file"],
|
||||
"currency": argd["currency"],
|
||||
"show-transactions": argd["transactions"] }
|
||||
return None
|
||||
|
||||
|
||||
def print_transactions(pb: PiggyBank) -> None:
|
||||
cur = CURRENCIES[pb.currency]
|
||||
def print_separator(l: str, m: str, r: str):
|
||||
print(f"{l}{'━'*21}{m}{'━'*5}{m}{m.join(['━'*12]*cur.count)}{r}")
|
||||
|
||||
print_separator("┏", "┳", "┓")
|
||||
print(f"┃{'Timestamp':^21}┃ I/O ┃" \
|
||||
f"{'┃'.join(f'{n:^12}' for n in cur.coin_names)}┃")
|
||||
print_separator("┣", "╋", "┫")
|
||||
for t in pb.transactions:
|
||||
print(f"┃ {t.timestamp.replace('T', ' ')} "
|
||||
f"┃{t.direction:^5}"
|
||||
f"┃{'┃'.join(f'{c:^12}' for c in t.coins)}┃")
|
||||
print_separator("┗", "┻", "┛")
|
||||
|
||||
def print_summary(pb: PiggyBank) -> None:
|
||||
cur = CURRENCIES[pb.currency]
|
||||
def print_separator(l: str, lm: str, rm: str, r:str):
|
||||
print(f"{l}{'━'*27}{lm}{rm.join(['━'*12]*cur.count)}{r}")
|
||||
|
||||
print_separator("┏", "┳", "┳", "┓")
|
||||
print(f"┃{cur.name:^27}┃{'┃'.join(f'{n:^12}' for n in cur.coin_names)}┃")
|
||||
print_separator("┣", "╋", "╋", "┫")
|
||||
s = sum_transactions(pb.transactions)
|
||||
print(f"┃{'Counts':^27}┃{'┃'.join(f'{c:^12}' for c in s)}┃")
|
||||
print_separator("┣", "╋", "╋", "┫")
|
||||
s = cur.multiply(s)
|
||||
print(f"┃{'Sums':^27}┃{'┃'.join(f'{c/100:^12.2f}' for c in s)}┃")
|
||||
print_separator("┣", "╋", "┻", "┫")
|
||||
s = sum(s)
|
||||
print(f"┃{'Total':^27}┃{s:^{12*cur.count+cur.count-1}}┃")
|
||||
print_separator("┗", "┻", "━", "┛")
|
||||
|
||||
|
||||
def print_supported_currencies() -> None:
|
||||
"""Print a list of supported currencies."""
|
||||
print("Supported currencies are:")
|
||||
for cur in CURRENCIES.keys():
|
||||
print(f" {cur:^4} ┃ {CURRENCIES[cur].name:^31}"
|
||||
f" ┃ {CURRENCIES[cur].description}")
|
||||
print("Default currency is", Configuration()["default-currency"])
|
||||
|
||||
|
||||
def load_user_defined_currencies() -> None:
|
||||
if not "currency" in Configuration().items:
|
||||
return
|
||||
for iso, cur in Configuration()["currency"].items():
|
||||
CURRENCIES[iso] = Currency.from_string(cur)
|
||||
|
||||
|
||||
def main():
|
||||
cargs = parse_common_arguments(' '.join(argv))
|
||||
if not cargs is None:
|
||||
if cargs["help"]:
|
||||
print(USAGE)
|
||||
exit()
|
||||
elif cargs["version"]:
|
||||
print(VERSION)
|
||||
exit()
|
||||
elif cargs["list-currencies"]:
|
||||
print_supported_currencies()
|
||||
exit()
|
||||
elif not cargs["default-currency"] is None:
|
||||
conf = Configuration()
|
||||
conf["default-currency"] = cargs["default-currency"]
|
||||
conf.save()
|
||||
exit()
|
||||
|
||||
args = parse_arguments(' '.join(argv))
|
||||
if not args:
|
||||
print(USAGE)
|
||||
exit()
|
||||
|
||||
try:
|
||||
load_user_defined_currencies()
|
||||
try:
|
||||
pb = PiggyBank.from_file(args["file"])
|
||||
except FileNotFoundError:
|
||||
if args["action"] == "in":
|
||||
currency = Configuration()["default-currency"] \
|
||||
if args["currency"] is None else args["currency"]
|
||||
pb = PiggyBank(currency)
|
||||
else:
|
||||
raise FileNotFoundError(f"{args['file']} is missing.")
|
||||
if args["action"] in ["in", "from"]:
|
||||
coins = complement_list_of_coins(args["coins"], pb.currency,
|
||||
args["reversed"])
|
||||
pb.transact(coins, TYPE_INCOME if args["action"] == "in" \
|
||||
else TYPE_OUTCOME)
|
||||
pb.save(args["file"])
|
||||
elif args["action"] == "show":
|
||||
print_summary(pb)
|
||||
if args["show-transactions"]:
|
||||
print_transactions(pb)
|
||||
except BaseCurrencyError as err:
|
||||
print(f"{type(err).__name__}:", err, file=stderr)
|
||||
except FileNotFoundError as err:
|
||||
print(f"{type(err).__name__}:", err, file=stderr)
|
||||
except ValueError as err:
|
||||
print(f"{type(err).__name__}:", err, file=stderr)
|
||||
except Exception as err:
|
||||
print(f"Something went exceptionally wrong. Error:",
|
||||
f"{type(err).__name__}:", err, file=stderr)
|
@ -1,61 +0,0 @@
|
||||
"""CLI: Put a set of coins into a piggy bank."""
|
||||
|
||||
from re import split, search
|
||||
from sys import argv, stderr
|
||||
|
||||
from piggybank.configuration import Configuration
|
||||
from piggybank.cli import complement_list_of_coins, handle_default_arguments
|
||||
from piggybank.currencies import CURRENCIES, BaseCurrencyError
|
||||
from piggybank.piggybank import PiggyBank
|
||||
|
||||
__all__ = ["main"]
|
||||
|
||||
|
||||
USAGE_PUT = "Usage: piggybank-put [-r|--reversed] COINS in FILE of CURRENCY\n" \
|
||||
"Put a set of coins in a piggybank. Set a currency of a new one.\n\n" \
|
||||
"-r, --reversed -- use reversed order of COINS (from greater to least);\n" \
|
||||
"COINS -- array of comma or whitespace separated coins;\n" \
|
||||
"in FILE -- .pb file name of your piggybank;\n" \
|
||||
"of CURRENCY -- set a currency for a new piggybank.\n"
|
||||
|
||||
|
||||
def parse_put_arguments(args):
|
||||
r = r"(?P<reversed>-r|--reversed)? ?(?P<coins>[\d ,]+) in (?P<file>\S+)(?= of (?P<currency>\S+))?"
|
||||
argd = search(r, args)
|
||||
if not argd is None:
|
||||
argd = argd.groupdict()
|
||||
return {
|
||||
"coins": list(map(int, split(r"\D",argd["coins"]))),
|
||||
"file": argd["file"],
|
||||
"currency": Configuration()["default-currency"] \
|
||||
if argd["currency"] is None else argd["currency"],
|
||||
"reversed": not argd["reversed"] is None }
|
||||
return None
|
||||
|
||||
|
||||
def main() -> None:
|
||||
handle_default_arguments(' '.join(argv[1:]), lambda: print(USAGE_PUT))
|
||||
args = parse_put_arguments(' '.join(argv[1:]))
|
||||
|
||||
if args is None:
|
||||
print(USAGE_PUT)
|
||||
exit()
|
||||
|
||||
try:
|
||||
try:
|
||||
piggybank = PiggyBank.from_file(args["file"])
|
||||
except FileNotFoundError:
|
||||
currency = Configuration()["default-currency"] \
|
||||
if args["currency"] is None else args["currency"]
|
||||
piggybank = PiggyBank(currency)
|
||||
coins = complement_list_of_coins(args["coins"], piggybank.currency,
|
||||
args["reversed"])
|
||||
piggybank.transact(coins)
|
||||
piggybank.save(args["file"])
|
||||
except BaseCurrencyError as err:
|
||||
print(f"{type(err).__name__}:", err, file=stderr)
|
||||
except ValueError as err:
|
||||
print(f"{type(err).__name__}:", err, file=stderr)
|
||||
except Exception as err:
|
||||
print(f"Something went exceptionally wrong. Error:",
|
||||
f"{type(err).__name__}:", err, file=stderr)
|
@ -1,108 +0,0 @@
|
||||
"""CLI: Show summarised information on a piggybank."""
|
||||
|
||||
from re import match
|
||||
from sys import argv, exit, stderr
|
||||
|
||||
from piggybank.cli import handle_default_arguments
|
||||
from piggybank.currencies import CURRENCIES, BaseCurrencyError
|
||||
from piggybank.piggybank import PiggyBank
|
||||
from piggybank.transaction import sum_transactions, multiply_transactions
|
||||
|
||||
__all__ = ["main"]
|
||||
|
||||
|
||||
USAGE_SHOW: str = "Usage: piggybank-show FILE [with t,transactions]\n\n" \
|
||||
"Show statistics about a piggybank.\n" \
|
||||
"FILE -- .pb file name of your piggybank;\n" \
|
||||
"with (t|transaction) -- also list all transactions.\n"
|
||||
|
||||
DEFAULT_COIN_CENTERING: int = 10
|
||||
|
||||
|
||||
def parse_show_arguments(args):
|
||||
r = r"^(?P<file>\S+)(?= with (?P<transactions>t|transactions))?"
|
||||
argd = match(r, args)
|
||||
if not argd is None:
|
||||
argd = argd.groupdict()
|
||||
return {
|
||||
"file": argd["file"],
|
||||
"transactions": not argd["transactions"] is None }
|
||||
return None
|
||||
|
||||
|
||||
def print_summary(piggybank: PiggyBank,
|
||||
centering: int = DEFAULT_COIN_CENTERING) -> None:
|
||||
"""Print summarised information on a piggy bank.
|
||||
Prints a table with totals of how much coins of which face value are in a
|
||||
piggy bank; A total sum converted to its currency for each face value and
|
||||
overall total sum in a currency of a piggy bank."""
|
||||
def print_separator(left="┣", lmiddle="╋", rmiddle="╋", right="┫"):
|
||||
line = rmiddle.join('━' * centering
|
||||
for _ in
|
||||
range(CURRENCIES[piggybank.currency]['count']))
|
||||
print(f"{left}{'━'*27}{lmiddle}{line}{right}")
|
||||
|
||||
cc = sum_transactions(piggybank.transactions)
|
||||
cs = multiply_transactions(piggybank.transactions, piggybank.currency)
|
||||
ct = sum(cc)
|
||||
|
||||
nline = "┃".join([f'{l:^{centering}}'
|
||||
for l in CURRENCIES[piggybank.currency]["names"]])
|
||||
nline_len = len(nline)
|
||||
|
||||
print_separator(left="┏", lmiddle="┳", rmiddle="━", right="┓")
|
||||
print(f"┃{'currency':^27}┃"
|
||||
f"{CURRENCIES[piggybank.currency]['name']:^{nline_len}}┃")
|
||||
print_separator(rmiddle="┳")
|
||||
print(f"┃{'face values':^27}┃{nline}┃")
|
||||
print_separator()
|
||||
print(f"┃{'amount':^27}┃{'┃'.join([f'{c:^{centering}}' for c in cc])}┃")
|
||||
print_separator()
|
||||
print(f"┃{'sum':^27}┃"
|
||||
f"{'┃'.join(['{:^{}.2f}'.format(c / 100, centering) for c in cs])}┃")
|
||||
print_separator(rmiddle="┻")
|
||||
print(f"┃{'total':^27}┃{'{:^{}.2f}'.format(ct / 100, nline_len)}┃")
|
||||
print_separator(left="┗", lmiddle="┻", rmiddle="━", right="┛")
|
||||
|
||||
|
||||
def print_transactions(piggybank, centering=DEFAULT_COIN_CENTERING):
|
||||
"""Print a list of all transactions stored in a piggy bank."""
|
||||
def print_separator(left="┏", middle="┳", right="┓"):
|
||||
line = middle.join('━' * centering
|
||||
for _ in
|
||||
range(CURRENCIES[piggybank.currency]['count']))
|
||||
print(f"{left}━━━━━━━━━━━━━━━━━━━━━{middle}━━━━━{middle}{line}{right}")
|
||||
|
||||
nline = "┃".join([f'{l:^{centering}}'
|
||||
for l in CURRENCIES[piggybank.currency]["names"]])
|
||||
|
||||
print_separator()
|
||||
print(f"┃{'Timestamp':^21}┃ I/O ┃{nline}┃")
|
||||
print_separator("┣", "╋", "┫")
|
||||
for tr in piggybank.transactions:
|
||||
coin_line = "┃".join([f'{c:^{centering}}' for c in tr.coins])
|
||||
ts = tr.timestamp.replace("T", " ")
|
||||
print(f"┃ {ts} ┃{tr.direction:^5}┃{coin_line}┃")
|
||||
print_separator("┗", "┻", "┛")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
handle_default_arguments(' '.join(argv[1:]), lambda: print(USAGE_SHOW))
|
||||
args = parse_show_arguments(' '.join(argv[1:]))
|
||||
|
||||
if args is None:
|
||||
print(USAGE_SHOW)
|
||||
exit()
|
||||
|
||||
try:
|
||||
piggybank = PiggyBank.from_file(args["file"])
|
||||
print_summary(piggybank)
|
||||
if args["transactions"]:
|
||||
print_transactions(piggybank)
|
||||
except BaseCurrencyError as err:
|
||||
print(f"{type(err).__name__}:", err, file=stderr)
|
||||
except FileNotFoundError as err:
|
||||
print(f"{type(err).__name__}:", f"{err} doesn't exist.", file=stderr)
|
||||
except Exception as err:
|
||||
print(f"Something went exceptionally wrong. Error:",
|
||||
f"{type(err).__name__}:", err, file=stderr)
|
@ -1,57 +0,0 @@
|
||||
"""CLI: Take a set of coins from a coin box."""
|
||||
|
||||
from re import match, split
|
||||
from sys import argv, exit, stderr
|
||||
|
||||
from piggybank import print_program_version
|
||||
from piggybank.configuration import Configuration
|
||||
from piggybank.cli import complement_list_of_coins, handle_default_arguments
|
||||
from piggybank.currencies import CURRENCIES, BaseCurrencyError
|
||||
from piggybank.piggybank import PiggyBank
|
||||
from piggybank.transaction import TYPE_OUTCOME
|
||||
|
||||
__all__ = ["main"]
|
||||
|
||||
|
||||
USAGE_TAKE: str = "Usage: piggybank-take [-r|--reversed] COINS from FILE\n\n" \
|
||||
"Take a set of coins from a piggybank.\n" \
|
||||
"-r, --reversed -- use reversed order of COINS (from greater to least);\n" \
|
||||
"COINS -- array of comma or whitespace separated coins;\n" \
|
||||
"from FILE -- .pb filename.\n"
|
||||
|
||||
|
||||
def parse_take_arguments(args):
|
||||
r = r"^(?P<reversed>-r|--reversed)? ?(?P<coins>[\d ,]+) from (?P<file>\S+)"
|
||||
argd = match(r, args)
|
||||
if not argd is None:
|
||||
argd = argd.groupdict()
|
||||
return {
|
||||
"coins": list(map(int, split(r"\D", argd["coins"]))),
|
||||
"file": argd["file"],
|
||||
"reversed": not argd["reversed"] is None }
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
handle_default_arguments(' '.join(argv[1:]), lambda: print(USAGE_TAKE))
|
||||
args = parse_take_arguments(' '.join(argv[1:]))
|
||||
|
||||
if args is None:
|
||||
print(USAGE_TAKE)
|
||||
exit()
|
||||
|
||||
try:
|
||||
piggybank = PiggyBank.from_file(args["file"])
|
||||
coins = complement_list_of_coins(args["coins"], piggybank.currency,
|
||||
args["reversed"])
|
||||
piggybank.transact(coins, TYPE_OUTCOME)
|
||||
piggybank.save(args["file"])
|
||||
except BaseCurrencyError as err:
|
||||
print(f"{type(err).__name__}:", err, file=stderr)
|
||||
except ValueError as err:
|
||||
print(f"{type(err).__name__}:", err, file=stderr)
|
||||
except FileNotFoundError as err:
|
||||
print(f"{type(err).__name__}:", f"{err} doesn't exist.", file=stderr)
|
||||
except Exception as err:
|
||||
print(f"Something went exceptionally wrong. Error:",
|
||||
f"{type(err).__name__}:", err, file=stderr)
|
@ -59,6 +59,10 @@ class Configuration:
|
||||
for key, value in self._configuration.items():
|
||||
cf.write(f"{key} = {value}\n")
|
||||
|
||||
@property
|
||||
def items(self) -> dict:
|
||||
return self._configuration
|
||||
|
||||
def __getitem__(self, key: str) -> Union[int, str, bool]:
|
||||
return self._configuration[key]
|
||||
|
||||
|
@ -128,7 +128,7 @@ CURRENCIES: Dict[str, Currency] = {
|
||||
[1, 5, 10, 50, 1_00, 2_00, 5_00, 10_00]),
|
||||
"SRUB": Currency("SRUB", "Russian ruble (shortened)",
|
||||
"Russian Federation. Excluding coins of 1 and 5 kopek.",
|
||||
8, ["10к.", "50к.", "1₽", "2₽", "5₽", "10₽"],
|
||||
6, ["10к.", "50к.", "1₽", "2₽", "5₽", "10₽"],
|
||||
[10, 50, 1_00, 2_00, 5_00, 10_00]),
|
||||
"BYN": Currency("BYN", "Belarusian ruble", "Belarus", 8,
|
||||
["1к.", "2к.", "5к.", "10к.", "20к.", "50к.", "1р.", "2р."],
|
||||
|
@ -23,10 +23,10 @@ class PiggyBank:
|
||||
|
||||
def transact(self, coins: List[int], direction: str = TYPE_INCOME) -> None:
|
||||
"""Make a transaction."""
|
||||
if len(coins) != CURRENCIES[self._currency]["count"]:
|
||||
if len(coins) != len(CURRENCIES[self._currency]):
|
||||
raise ValueError("Length of passed coins list doesn't match the " \
|
||||
f"currency's coins count. ({len(coins)} " \
|
||||
f"!= {CURRENCIES[self._currency]['count']})")
|
||||
f"!= {len(CURRENCIES[self._currency])})")
|
||||
self._last_transaction = Transaction(coins, direction)
|
||||
self._transactions.append(self._last_transaction)
|
||||
for coin_count in sum_transactions(self._transactions):
|
||||
|
Loading…
Reference in New Issue
Block a user