def test_replace_item(): repo = Repository() repo.add_item(0) repo.add_item(1) repo.add_item(1) repo.add_item(1) repo.replace_item(lambda item: item == 1, 0) assert repo.get_items() == [0, 0, 1, 1] repo.undo() assert repo.get_items() == [0, 1, 1, 1]
class TransactionCommands(clisys.CLISys): def __init__(self): super().__init__() self.__repo = Repository() self.init_repo() @clisys.command(name='help') def help(self, args): """ Displays help for all commands or a single command. help help <command> """ count = len(args) commands = self.get_commands() if count == 0: for cmd_name, cmd in commands.items(): print(f'{cmd_name}: {cmd.__doc__}') elif count == 1: cmd_name = args[0] if not (cmd_name in commands.keys()): raise clisys.InvalidArgument(args[0]) cmd = commands[cmd_name] print(f'{cmd_name}: {cmd.__doc__}') @clisys.command(name='test') def test(self, args): """ Test command. """ print('TEST') @clisys.command(name='exit') def exit_command(self, args): """ Exits the program. """ exit(0) @clisys.command(name='add') def add_transaction(self, args): """ Add a transaction to the list. add <value> <type> <description> """ try: value = int(args[0]) except ValueError: raise clisys.InvalidArgument(args[0]) type = args[1] description = args[2] transaction = Transaction(int(datetime.today().strftime('%d')), value, type, description) self.__repo.add_item(transaction) @clisys.command(name='insert') def insert_transaction(self, args): """ Insert a transaction in the list. insert <day> <value> <type> <description> """ try: day = int(args[0]) except ValueError: raise clisys.InvalidArgument(args[0]) try: value = int(args[1]) except ValueError: raise clisys.InvalidArgument(args[1]) type = args[2] description = args[3] transaction = Transaction(day, value, type, description) self.__repo.add_item(transaction) @clisys.command(name='remove') def remove_transaction(self, args): """ Remove transactions from the list. remove <day> remove <start day> to <end day> remove <type> """ count = len(args) if count == 1: try: day = int(args[0]) self.__repo.remove_items(lambda t: t.get_day() == day) except ValueError: type = args[0] self.__repo.remove_items(lambda t: t.get_type() == type) elif count == 3: if args[1] != 'to': raise clisys.InvalidArgument(args[1]) start_day = int(args[0]) end_day = int(args[2]) self.__repo.remove_items( lambda t: start_day <= t.get_day() <= end_day) else: raise clisys.InvalidArgumentCount @clisys.command(name='replace') def replace_transaction(self, args): """ Replace the amount of a transaction with a given value. replace <day> <type> <description> with <value> """ if len(args) != 5: raise clisys.InvalidArgumentCount if args[3] != 'with': raise clisys.InvalidArgument(args[3]) try: day = int(args[0]) except ValueError: raise clisys.InvalidArgument(args[0]) type = args[1] description = args[2] try: value = int(args[4]) except ValueError: raise clisys.InvalidArgument(args[4]) self.__repo.replace_item( lambda t: t.get_day() == day and t.get_type() == type and t. get_description() == description, Transaction(day, value, type, description)) @clisys.command(name='list') def list_transactions(self, args): """ Display the list of transactions. list list <type> list [ < | = | > ] <value> list balance <day> """ count = len(args) if count == 0: display_transactions(self.__repo.get_items()) elif count == 1: type = args[0] display_transactions( self.__repo.get_items(lambda t: t.get_type() == type)) elif count == 2: option = args[0] if option == 'balance': try: day = int(args[1]) except ValueError: raise clisys.InvalidArgument(args[1]) balance = get_balance(self.__repo, day) print(f"Balance on day {day}: {balance}") elif option in ['<', '=', '>']: try: amount = int(args[1]) except ValueError: raise clisys.InvalidArgument(args[1]) if option == '<': display_transactions( self.__repo.get_items( lambda t: t.get_money_amount() < amount)) elif option == '=': display_transactions( self.__repo.get_items( lambda t: t.get_money_amount() == amount)) elif option == '>': display_transactions( self.__repo.get_items( lambda t: t.get_money_amount() > amount)) else: raise clisys.InvalidArgument(args[0]) else: raise clisys.InvalidArgumentCount @clisys.command(name='sum') def sum_transactions(self, args): """ Displays the total amount from a transaction type. sum <type> """ if len(args) > 1: raise clisys.InvalidArgumentCount type = args[0] result = get_sum(self.__repo, type) print(f'Total amount from "{type}" transactions: {result}') @clisys.command(name='max') def max_transaction(self, args): if len(args) != 2: raise clisys.InvalidArgumentCount type = args[0] try: day = int(args[1]) except ValueError: raise clisys.InvalidArgument(args[1]) result = get_max(self.__repo, type, day) if result is None: print(f'No transaction of type "{type}" on day {day}.') else: print( f'The maximum "{type}" transaction on day {day}: "{result.get_description()}: {result.get_money_amount()}"' ) @clisys.command(name='filter') def filter_transactions(self, args): """ Filters the transactions. filter <type> filter <type> <value> """ count = len(args) if count == 1: type = args[0] self.__repo.remove_items(lambda t: t.get_type() != type) elif count == 2: type = args[0] try: value = int(args[1]) except ValueError: raise clisys.InvalidArgument([args[1]]) self.__repo.remove_items(lambda t: t.get_type() != type or t. get_money_amount() >= value) print('Transactions filtered successfully!') @clisys.command(name='undo') def undo(self, args): """ Undo the last command that changed the transactions list. undo """ try: self.__repo.undo() print('Undo executed successfully!') except cmdsys.EmptyActionsStack: print('Nothing to undo.') @clisys.command(name='redo') def redo(self, args): """ Redo the last undo-ed command. redo """ try: self.__repo.redo() print('Redo executed successfully!') except cmdsys.EmptyUndoStack: print('Nothing to redo.') @clisys.exception_handler def handle_exceptions(self, exception: Exception): """ Handles exceptions raised in commands. :param exception: The exception. :return: """ try: raise exception except clisys.InvalidCommand as e: print(f'Invalid command: "{str(e.command_name)}" .') except clisys.InvalidArgument as e: print(f'Invalid argument: "{str(e.argument_name)}" .') except clisys.InvalidArgumentCount: print(f'Invalid argument count.') @clisys.input_handler def get_input(self): """ Gets the input and returns it as a list :return: A list of strings. """ i = input('\n> ') i = re.split(r' +', i) return i def init_repo(self): self.__repo.add_item(Transaction(2, 1909, 'in', 'freelancing')) self.__repo.add_item(Transaction(24, 178, 'out', 'food')) self.__repo.add_item(Transaction(1, 1200, 'out', 'rent')) self.__repo.add_item(Transaction(14, 54, 'out', 'food')) self.__repo.add_item(Transaction(14, 55023, 'in', 'salary')) self.__repo.add_item(Transaction(16, 550, 'in', 'freelancing')) self.__repo.add_item(Transaction(23, 1200, 'out', 'project')) self.__repo.add_item(Transaction(2, 230, 'out', 'food')) self.__repo.add_item(Transaction(16, 176, 'out', 'food')) self.__repo.add_item(Transaction(5, 188, 'out', 'food'))