1
0
PiggyBank/piggybank/cli/show.py

105 lines
4.1 KiB
Python

"""CLI: Show summarised information on a piggybank."""
from re import match
from sys import argv, exit, stderr
from piggybank import print_program_version, PIGGYBANK_FILE_EXTENSION
from piggybank.configuration import Configuration
from piggybank.cli import handle_default_arguments
from piggybank.currencies import CURRENCIES, \
BaseCurrencyError
from piggybank.piggybank import PiggyBank
__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": argd["transactions"] is 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, cs, ct = piggybank.count, piggybank.sum, piggybank.total
cline = "".join([f'{l:^{centering}}'
for l in CURRENCIES[piggybank.currency]["names"]])
cline_len = len(cline)
print_separator(left="", lmiddle="", rmiddle="", right="")
print(f"{'currency':^27}"
f"{CURRENCIES[piggybank.currency]['name']:^{cline_len}}")
print_separator(rmiddle="")
print(f"{'face values':^27}{cline}")
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, cline_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}")
cline = "".join([f'{l:^{centering}}'
for l in CURRENCIES[piggybank.currency]["names"]])
print_separator()
print(f"{'Timestamp':^21}┃ I/O ┃{cline}")
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), lambda: print(USAGE_SHOW))
args = parse_show_arguments(' '.join(argv))
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)