From 1e111b3e358439654fc792eb6275283c8cf383e1 Mon Sep 17 00:00:00 2001 From: At0mn1yIvan Date: Tue, 27 Sep 2022 23:14:44 +0300 Subject: [PATCH 01/12] Solution --- homeworks/At0mn1yIvan/2/main.py | 72 +++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 homeworks/At0mn1yIvan/2/main.py diff --git a/homeworks/At0mn1yIvan/2/main.py b/homeworks/At0mn1yIvan/2/main.py new file mode 100644 index 0000000..5c9fe60 --- /dev/null +++ b/homeworks/At0mn1yIvan/2/main.py @@ -0,0 +1,72 @@ +class Array(object): + + def __init__(self, *args): + self._data = tuple(args) + + def append(self, obj): + self._data = (*self._data, obj) + + def __add__(self, other): + return Array(*(self._data + other._data)) + + def __radd__(self, other): + return Array(*(other._data + self._data)) + + def __len__(self): + return len(self._data) + + def index(self, obj): + + if obj in self._data: + return self._data.index(obj) + else: + return -1 + + def __getitem__(self, index): + return self._data[index] + + def printArr(self): + print(self._data) + + +#test + +#1 +print("_______№1_______") +a = Array() +b = Array(1) +c = Array(1, 2, 3) +a.printArr() +b.printArr() +c.printArr() + +#2 +print("_______№2_______") +a.append(2) +a.printArr() + +#3 +print("_______№3_______") +a = b + c +a.printArr() +a += c +a.printArr() + +#4 +print("_______№4_______") +print(len(a)) + +#5 +print("_______№5_______") +print(c.index(2)) +print(c.index(5)) + +#6 +print("_______№6_______") +for element in c: + print(element) + +#7 +print("_______№7_______") +print(Array('a', 'b', 'c', 'd')[0]) +print(c[2]) \ No newline at end of file From 05a0fe5030e303d0899be6317b1e81cb2163deff Mon Sep 17 00:00:00 2001 From: At0mn1yIvan Date: Wed, 28 Sep 2022 21:05:04 +0300 Subject: [PATCH 02/12] Solution --- practice/At0mn1yIvan/1/game.py | 83 ++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 practice/At0mn1yIvan/1/game.py diff --git a/practice/At0mn1yIvan/1/game.py b/practice/At0mn1yIvan/1/game.py new file mode 100644 index 0000000..9b3de4f --- /dev/null +++ b/practice/At0mn1yIvan/1/game.py @@ -0,0 +1,83 @@ +# `random` module is used to shuffle field, see: +# https://docs.python.org/3/library/random.html#random.shuffle +import random +# Empty tile, there's only one empty cell on a field: +EMPTY_MARK = 'x' + +# Dictionary of possible moves if a form of: +# key -> delta to move the empty tile on a field. +MOVES = { + 'w': -4, + 's': 4, + 'a': -1, + 'd': 1, +} + +def shuffle_field(): + + my_field = list() + for i in range(1, 16): + my_field.append(i) + my_field.append(EMPTY_MARK) + for move in range(100): + random.shuffle(my_field) + return my_field + + +def print_field(field): + + for i in range(len(field)): + if field[i] == EMPTY_MARK or field[i] < 10: + print(' ', end='') + print(field[i], end=' | ') + if i in [3, 7, 11]: + print() + print() + + +def is_game_finished(field): + + for i in range(len(field) - 1): + if (i + 1) != field[i]: + return False + return True + + +def perform_move(field, key): + emp_ind = 0 + for i in field: + if i == EMPTY_MARK: + emp_ind = field.index(i) + break + if emp_ind % 4 == 0 and key == 'a': + return None + if emp_ind % 4 == 3 and key == 'd': + return None + if emp_ind + MOVES[key] < 0: + return None + if emp_ind + MOVES[key] > 15: + return None + + field[emp_ind], field[emp_ind + MOVES[key]] = field[emp_ind + MOVES[key]], field[emp_ind] + return field + +def handle_user_input(): + + my_key = input() + if my_key not in ['w', 'a', 's', 'd']: + return None + return my_key + + +def main(): + game_field = shuffle_field() + while not is_game_finished(game_field): + print_field(game_field) + perform_move(game_field, handle_user_input()) + print("YOU WIN") + + +if __name__ == '__main__': + # See what this means: + # http://stackoverflow.com/questions/419163/what-does-if-name-main-do + main() From a913ad6180ea71b5323a713e5d686fd8bd8cdd3c Mon Sep 17 00:00:00 2001 From: At0mn1yIvan Date: Mon, 3 Oct 2022 22:19:49 +0300 Subject: [PATCH 03/12] Solution --- homeworks/At0mn1yIvan/2/main.py | 72 ------------------------- homeworks/At0mn1yIvan/3/contract.py | 37 +++++++++++++ practice/At0mn1yIvan/1/game.py | 83 ----------------------------- 3 files changed, 37 insertions(+), 155 deletions(-) delete mode 100644 homeworks/At0mn1yIvan/2/main.py create mode 100644 homeworks/At0mn1yIvan/3/contract.py delete mode 100644 practice/At0mn1yIvan/1/game.py diff --git a/homeworks/At0mn1yIvan/2/main.py b/homeworks/At0mn1yIvan/2/main.py deleted file mode 100644 index 5c9fe60..0000000 --- a/homeworks/At0mn1yIvan/2/main.py +++ /dev/null @@ -1,72 +0,0 @@ -class Array(object): - - def __init__(self, *args): - self._data = tuple(args) - - def append(self, obj): - self._data = (*self._data, obj) - - def __add__(self, other): - return Array(*(self._data + other._data)) - - def __radd__(self, other): - return Array(*(other._data + self._data)) - - def __len__(self): - return len(self._data) - - def index(self, obj): - - if obj in self._data: - return self._data.index(obj) - else: - return -1 - - def __getitem__(self, index): - return self._data[index] - - def printArr(self): - print(self._data) - - -#test - -#1 -print("_______№1_______") -a = Array() -b = Array(1) -c = Array(1, 2, 3) -a.printArr() -b.printArr() -c.printArr() - -#2 -print("_______№2_______") -a.append(2) -a.printArr() - -#3 -print("_______№3_______") -a = b + c -a.printArr() -a += c -a.printArr() - -#4 -print("_______№4_______") -print(len(a)) - -#5 -print("_______№5_______") -print(c.index(2)) -print(c.index(5)) - -#6 -print("_______№6_______") -for element in c: - print(element) - -#7 -print("_______№7_______") -print(Array('a', 'b', 'c', 'd')[0]) -print(c[2]) \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/3/contract.py b/homeworks/At0mn1yIvan/3/contract.py new file mode 100644 index 0000000..b7b6851 --- /dev/null +++ b/homeworks/At0mn1yIvan/3/contract.py @@ -0,0 +1,37 @@ +class ContractError(Exception): + """We use this error when someone breaks our contract.""" + + +#: Special value, that indicates that validation for this type is not required. +Any = object() + + +def contract(arg_types=None, return_type=None, raises=None): + def contract_decorator(func): + def wrapped(*args, **kwargs): + all_args = tuple(args + tuple(kwargs.values())) + if arg_types is not None: + for elem in range(len(arg_types)): + if arg_types[elem] != Any: + if not isinstance(all_args[elem], arg_types[elem]): + raise ContractError("Invalid ArgType Error") + try: + result = func(*args, **kwargs) + except (Exception if raises is None or Any in raises else raises) as exc: + raise exc + except Exception as ex: + raise ContractError from ex + if return_type is not None: + if not isinstance(result, return_type): + raise ContractError("Invalid ReturnType Error") + return result + return wrapped + return contract_decorator + + +@contract(arg_types=(Any, int), return_type=None, raises=(ZeroDivisionError,)) +def add_two_numbers(first, second): + return first + second + + +print(add_two_numbers(15, 7.5)) \ No newline at end of file diff --git a/practice/At0mn1yIvan/1/game.py b/practice/At0mn1yIvan/1/game.py deleted file mode 100644 index 9b3de4f..0000000 --- a/practice/At0mn1yIvan/1/game.py +++ /dev/null @@ -1,83 +0,0 @@ -# `random` module is used to shuffle field, see: -# https://docs.python.org/3/library/random.html#random.shuffle -import random -# Empty tile, there's only one empty cell on a field: -EMPTY_MARK = 'x' - -# Dictionary of possible moves if a form of: -# key -> delta to move the empty tile on a field. -MOVES = { - 'w': -4, - 's': 4, - 'a': -1, - 'd': 1, -} - -def shuffle_field(): - - my_field = list() - for i in range(1, 16): - my_field.append(i) - my_field.append(EMPTY_MARK) - for move in range(100): - random.shuffle(my_field) - return my_field - - -def print_field(field): - - for i in range(len(field)): - if field[i] == EMPTY_MARK or field[i] < 10: - print(' ', end='') - print(field[i], end=' | ') - if i in [3, 7, 11]: - print() - print() - - -def is_game_finished(field): - - for i in range(len(field) - 1): - if (i + 1) != field[i]: - return False - return True - - -def perform_move(field, key): - emp_ind = 0 - for i in field: - if i == EMPTY_MARK: - emp_ind = field.index(i) - break - if emp_ind % 4 == 0 and key == 'a': - return None - if emp_ind % 4 == 3 and key == 'd': - return None - if emp_ind + MOVES[key] < 0: - return None - if emp_ind + MOVES[key] > 15: - return None - - field[emp_ind], field[emp_ind + MOVES[key]] = field[emp_ind + MOVES[key]], field[emp_ind] - return field - -def handle_user_input(): - - my_key = input() - if my_key not in ['w', 'a', 's', 'd']: - return None - return my_key - - -def main(): - game_field = shuffle_field() - while not is_game_finished(game_field): - print_field(game_field) - perform_move(game_field, handle_user_input()) - print("YOU WIN") - - -if __name__ == '__main__': - # See what this means: - # http://stackoverflow.com/questions/419163/what-does-if-name-main-do - main() From 09b9e9d50f49ed92a3e68c2397c4f4ae79b7460e Mon Sep 17 00:00:00 2001 From: At0mn1yIvan Date: Wed, 12 Oct 2022 20:49:55 +0300 Subject: [PATCH 04/12] Solution --- homeworks/At0mn1yIvan/3/contract.py | 37 ----- homeworks/At0mn1yIvan/4/.idea/.gitignore | 3 + homeworks/At0mn1yIvan/4/.idea/HW4.iml | 10 ++ .../inspectionProfiles/profiles_settings.xml | 6 + homeworks/At0mn1yIvan/4/.idea/misc.xml | 4 + homeworks/At0mn1yIvan/4/.idea/modules.xml | 8 ++ homeworks/At0mn1yIvan/4/tests/__init__.py | 0 homeworks/At0mn1yIvan/4/tests/conftest.py | 5 + .../At0mn1yIvan/4/tests/test_done_command.py | 30 ++++ .../4/tests/test_representations.py | 18 +++ .../At0mn1yIvan/4/tests/test_to_read_item.py | 43 ++++++ .../4/tests/test_undone_command.py | 30 ++++ homeworks/At0mn1yIvan/4/todo/__init__.py | 0 homeworks/At0mn1yIvan/4/todo/__main__.py | 28 ++++ homeworks/At0mn1yIvan/4/todo/commands.py | 131 ++++++++++++++++++ .../At0mn1yIvan/4/todo/custom_exceptions.py | 2 + homeworks/At0mn1yIvan/4/todo/models.py | 52 +++++++ homeworks/At0mn1yIvan/4/todo/reflection.py | 35 +++++ homeworks/At0mn1yIvan/4/todo/runtime.py | 52 +++++++ homeworks/At0mn1yIvan/4/todo/storage.py | 21 +++ 20 files changed, 478 insertions(+), 37 deletions(-) delete mode 100644 homeworks/At0mn1yIvan/3/contract.py create mode 100644 homeworks/At0mn1yIvan/4/.idea/.gitignore create mode 100644 homeworks/At0mn1yIvan/4/.idea/HW4.iml create mode 100644 homeworks/At0mn1yIvan/4/.idea/inspectionProfiles/profiles_settings.xml create mode 100644 homeworks/At0mn1yIvan/4/.idea/misc.xml create mode 100644 homeworks/At0mn1yIvan/4/.idea/modules.xml create mode 100644 homeworks/At0mn1yIvan/4/tests/__init__.py create mode 100644 homeworks/At0mn1yIvan/4/tests/conftest.py create mode 100644 homeworks/At0mn1yIvan/4/tests/test_done_command.py create mode 100644 homeworks/At0mn1yIvan/4/tests/test_representations.py create mode 100644 homeworks/At0mn1yIvan/4/tests/test_to_read_item.py create mode 100644 homeworks/At0mn1yIvan/4/tests/test_undone_command.py create mode 100644 homeworks/At0mn1yIvan/4/todo/__init__.py create mode 100644 homeworks/At0mn1yIvan/4/todo/__main__.py create mode 100644 homeworks/At0mn1yIvan/4/todo/commands.py create mode 100644 homeworks/At0mn1yIvan/4/todo/custom_exceptions.py create mode 100644 homeworks/At0mn1yIvan/4/todo/models.py create mode 100644 homeworks/At0mn1yIvan/4/todo/reflection.py create mode 100644 homeworks/At0mn1yIvan/4/todo/runtime.py create mode 100644 homeworks/At0mn1yIvan/4/todo/storage.py diff --git a/homeworks/At0mn1yIvan/3/contract.py b/homeworks/At0mn1yIvan/3/contract.py deleted file mode 100644 index b7b6851..0000000 --- a/homeworks/At0mn1yIvan/3/contract.py +++ /dev/null @@ -1,37 +0,0 @@ -class ContractError(Exception): - """We use this error when someone breaks our contract.""" - - -#: Special value, that indicates that validation for this type is not required. -Any = object() - - -def contract(arg_types=None, return_type=None, raises=None): - def contract_decorator(func): - def wrapped(*args, **kwargs): - all_args = tuple(args + tuple(kwargs.values())) - if arg_types is not None: - for elem in range(len(arg_types)): - if arg_types[elem] != Any: - if not isinstance(all_args[elem], arg_types[elem]): - raise ContractError("Invalid ArgType Error") - try: - result = func(*args, **kwargs) - except (Exception if raises is None or Any in raises else raises) as exc: - raise exc - except Exception as ex: - raise ContractError from ex - if return_type is not None: - if not isinstance(result, return_type): - raise ContractError("Invalid ReturnType Error") - return result - return wrapped - return contract_decorator - - -@contract(arg_types=(Any, int), return_type=None, raises=(ZeroDivisionError,)) -def add_two_numbers(first, second): - return first + second - - -print(add_two_numbers(15, 7.5)) \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/4/.idea/.gitignore b/homeworks/At0mn1yIvan/4/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/homeworks/At0mn1yIvan/4/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/homeworks/At0mn1yIvan/4/.idea/HW4.iml b/homeworks/At0mn1yIvan/4/.idea/HW4.iml new file mode 100644 index 0000000..74d515a --- /dev/null +++ b/homeworks/At0mn1yIvan/4/.idea/HW4.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/4/.idea/inspectionProfiles/profiles_settings.xml b/homeworks/At0mn1yIvan/4/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/homeworks/At0mn1yIvan/4/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/4/.idea/misc.xml b/homeworks/At0mn1yIvan/4/.idea/misc.xml new file mode 100644 index 0000000..d5637fc --- /dev/null +++ b/homeworks/At0mn1yIvan/4/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/4/.idea/modules.xml b/homeworks/At0mn1yIvan/4/.idea/modules.xml new file mode 100644 index 0000000..37e6459 --- /dev/null +++ b/homeworks/At0mn1yIvan/4/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/4/tests/__init__.py b/homeworks/At0mn1yIvan/4/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/homeworks/At0mn1yIvan/4/tests/conftest.py b/homeworks/At0mn1yIvan/4/tests/conftest.py new file mode 100644 index 0000000..e846edf --- /dev/null +++ b/homeworks/At0mn1yIvan/4/tests/conftest.py @@ -0,0 +1,5 @@ +import os +import sys + +BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) +sys.path.append(BASE_DIR) diff --git a/homeworks/At0mn1yIvan/4/tests/test_done_command.py b/homeworks/At0mn1yIvan/4/tests/test_done_command.py new file mode 100644 index 0000000..83a6927 --- /dev/null +++ b/homeworks/At0mn1yIvan/4/tests/test_done_command.py @@ -0,0 +1,30 @@ +def test_class_exists(): + from todo.commands import DoneCommand + + assert isinstance(DoneCommand, type) + + +def test_command_label_in_list(): + from todo.commands import DoneCommand + from todo.runtime import get_routes + + assert DoneCommand().label in get_routes() + + +def test_command_execution(monkeypatch): + from todo.commands import DoneCommand + from todo.runtime import perform_command + from todo.models import Storage, ToDoItem + + monkeypatch.setitem(__builtins__, 'input', lambda _: 0) + + item = ToDoItem('test') + item.done = False + + s = Storage() + s.items.clear() + s.items.append(item) + + perform_command(DoneCommand().label) + + assert item.done is True diff --git a/homeworks/At0mn1yIvan/4/tests/test_representations.py b/homeworks/At0mn1yIvan/4/tests/test_representations.py new file mode 100644 index 0000000..07043c8 --- /dev/null +++ b/homeworks/At0mn1yIvan/4/tests/test_representations.py @@ -0,0 +1,18 @@ +def test_to_buy_item(): + from todo.models import ToBuyItem + + item = ToBuyItem('header', 'price') + assert str(item).startswith('- ToBuy: ') + + item.done = True + assert str(item).startswith('+ ToBuy: ') + + +def test_to_do_item(): + from todo.models import ToDoItem + + item = ToDoItem('subject') + assert str(item).startswith('- ToDo: ') + + item.done = True + assert str(item).startswith('+ ToDo: ') diff --git a/homeworks/At0mn1yIvan/4/tests/test_to_read_item.py b/homeworks/At0mn1yIvan/4/tests/test_to_read_item.py new file mode 100644 index 0000000..b1ea1e3 --- /dev/null +++ b/homeworks/At0mn1yIvan/4/tests/test_to_read_item.py @@ -0,0 +1,43 @@ +def test_class_exists(): + from todo.models import ToReadItem + + assert isinstance(ToReadItem, type) + + +def test_there_are_attributes(): + from todo.models import ToReadItem + + heading = 'test' + url = 'http://ya.ru' + item = ToReadItem(heading, url) + + assert item.heading == heading + assert item.url == url + assert item.done is False + + +def test_fabric_method(monkeypatch): + from todo.models import ToReadItem + + value = 'some input' + + monkeypatch.setitem(__builtins__, 'input', lambda _: value) + item = ToReadItem.construct() + + assert item.heading == value + assert item.url == value + assert item.done is False + + +def test_representation(): + from todo.models import ToReadItem + + heading = 'test' + url = 'http://ya.ru' + item = ToReadItem(heading, url) + + assert str(item) == '- ToRead: {} {}'.format(heading, url) + + item.done = True + + assert str(item) == '+ ToRead: {} {}'.format(heading, url) diff --git a/homeworks/At0mn1yIvan/4/tests/test_undone_command.py b/homeworks/At0mn1yIvan/4/tests/test_undone_command.py new file mode 100644 index 0000000..b25bedf --- /dev/null +++ b/homeworks/At0mn1yIvan/4/tests/test_undone_command.py @@ -0,0 +1,30 @@ +def test_class_exists(): + from todo.commands import UndoneCommand + + assert isinstance(UndoneCommand, type) + + +def test_command_label_in_list(): + from todo.commands import UndoneCommand + from todo.runtime import get_routes + + assert UndoneCommand().label in get_routes() + + +def test_command_execution(monkeypatch): + from todo.commands import UndoneCommand + from todo.runtime import perform_command + from todo.models import Storage, ToDoItem + + monkeypatch.setitem(__builtins__, 'input', lambda _: 0) + + item = ToDoItem('test') + item.done = True + + s = Storage() + s.items.clear() + s.items.append(item) + + perform_command(UndoneCommand().label) + + assert item.done is False diff --git a/homeworks/At0mn1yIvan/4/todo/__init__.py b/homeworks/At0mn1yIvan/4/todo/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/homeworks/At0mn1yIvan/4/todo/__main__.py b/homeworks/At0mn1yIvan/4/todo/__main__.py new file mode 100644 index 0000000..55f9f2c --- /dev/null +++ b/homeworks/At0mn1yIvan/4/todo/__main__.py @@ -0,0 +1,28 @@ +""" +Main file. Contains program execution logic. +""" + +from todo.custom_exceptions import UserExitException +from todo.runtime import parse_user_input, perform_command + + +def main(): + """ + Main method, works infinitely until user runs `exit` command. + Or hits `Ctrl+C` in the console. + """ + while True: + try: + perform_command(parse_user_input()) + except UserExitException: + break + except Exception as ex: + print('You have done something wrong!', ex) + + +if __name__ == '__main__': + try: + main() + except KeyboardInterrupt: + print() + print('Shutting down, bye!') diff --git a/homeworks/At0mn1yIvan/4/todo/commands.py b/homeworks/At0mn1yIvan/4/todo/commands.py new file mode 100644 index 0000000..330af74 --- /dev/null +++ b/homeworks/At0mn1yIvan/4/todo/commands.py @@ -0,0 +1,131 @@ + +from todo.custom_exceptions import UserExitException +from todo.models import BaseItem +from todo.reflection import find_classes + + +class BaseCommand(object): + label: str + + def perform(self, store): + raise NotImplementedError() + + +class ListCommand(BaseCommand): + label = 'list' + + def perform(self, store): + if len(store.items) == 0: + print('There are no items in the storage.') + return + + for index, obj in enumerate(store.items): + print('{0}: {1}'.format(index, str(obj))) + + +class NewCommand(BaseCommand): + label = 'new' + + def perform(self, store): + classes = self._load_item_classes() + + print('Select item type:') + for index, name in enumerate(classes.keys()): + print('{0}: {1}'.format(index, name)) + + selection = None + selected_key = None + + while True: + try: + selected_key = self._select_item(classes) + except ValueError: + print('Bad input, try again.') + except IndexError: + print('Wrong index, try again.') + else: + break + + selected_class = classes[selected_key] + print('Selected: {0}'.format(selected_class.__name__)) + print() + + new_object = selected_class.construct() + + store.items.append(new_object) + + print('Added {0}'.format(str(new_object))) + print() + return new_object + + + def _load_item_classes(self) -> dict: + # Dynamic load: + return dict(find_classes(BaseItem)) + + + def _select_item(self, classes): + selection = int(input('Input number: ')) + if selection < 0: + raise IndexError('Index needs to be >0') + return list(classes.keys())[selection] + + +class MarkCommand(object): + + def perform(self, store): + k = 0 + + for obj in store.items: + if str(obj)[0] == self.char_command: + k += 1 + if k == 0: + print("There are no {0} items in the storage.".format(self.char_command)) + return + + for index, obj in enumerate(store.items): + if str(obj)[0] == self.char_command: + print('{0}: {1}'.format(index, str(obj))) + + selected_item = self.select_item(store) + + print("{0} has been {1}\n".format(selected_item, self.operation)) + + operation = getattr(selected_item, str(self.operation), None) + assert operation is not None + operation() + + def select_item(self, store): + while True: + try: + user_selection = int(input("Input number of item: ")) + if user_selection < 0 or str(store.items[user_selection])[0] != self.char_command: + raise IndexError() + except ValueError: + print("Bad input, try again") + except IndexError: + print("Bad index, try again") + else: + break + if store.items is None: + print("There are no items in storage") + return store.items[user_selection] + + +class DoneCommand(MarkCommand, BaseCommand): + label = "done" + char_command = '-' + operation = "mark_done" + + +class UndoneCommand(MarkCommand, BaseCommand): + label = "undone" + char_command = '+' + operation = "mark_undone" + + +class ExitCommand(BaseCommand): + label = 'exit' + + def perform(self, _store): + raise UserExitException('See you next time!') diff --git a/homeworks/At0mn1yIvan/4/todo/custom_exceptions.py b/homeworks/At0mn1yIvan/4/todo/custom_exceptions.py new file mode 100644 index 0000000..5e8963c --- /dev/null +++ b/homeworks/At0mn1yIvan/4/todo/custom_exceptions.py @@ -0,0 +1,2 @@ +class UserExitException(Exception): + """We use this exception when user wants to exit.""" diff --git a/homeworks/At0mn1yIvan/4/todo/models.py b/homeworks/At0mn1yIvan/4/todo/models.py new file mode 100644 index 0000000..cac7010 --- /dev/null +++ b/homeworks/At0mn1yIvan/4/todo/models.py @@ -0,0 +1,52 @@ +class BaseItem(object): + def __init__(self, heading): + self.heading = heading + self.done = False #TODO: make sure we can use it... + + def __repr__(self): + return self.__class__.__name__ + + def mark_done(self): + self.done = True + + def mark_undone(self): + self.done = False + + def __str__(self): + return "{0} {1}".format('+' if self.done else '-', self.__repr__()) + + @classmethod + def construct(cls): + raise NotImplementedError() + + +class ToDoItem(BaseItem): + def __str__(self): + return '{0}: {1}'.format( + super().__str__(), + self.heading, + ) + + @classmethod + def construct(cls): + heading = input('Input heading: ') + return cls(heading) + + +class ToBuyItem(BaseItem): + def __init__(self, heading, price): + super().__init__(heading) + self.price = price + + def __str__(self): + return '{0}: {1} for {2}'.format( + super().__str__(), + self.heading, + self.price, + ) + + @classmethod + def construct(cls): + heading = input('Input heading: ') + price = input('Input price: ') + return cls(heading, price) diff --git a/homeworks/At0mn1yIvan/4/todo/reflection.py b/homeworks/At0mn1yIvan/4/todo/reflection.py new file mode 100644 index 0000000..40dcfbf --- /dev/null +++ b/homeworks/At0mn1yIvan/4/todo/reflection.py @@ -0,0 +1,35 @@ +import inspect +import sys + + +def find_classes(base_class) -> tuple: + """ + Finds all subclasses of a class inside module. + + :param base_class: Base class to search children. + :return: tuple of subclasses + """ + return inspect.getmembers( + sys.modules[base_class.__module__], + _reflect_filter(base_class), + ) + + +def _reflect_filter(base_class): + """ + Reflection is used to load modules dynamically. + + This method is complex. It does some dark magic. + How is it even possible to understand it? + + :param base_class: Target base class + :return: function to filter only subclasses of `base_class` + """ + + def class_filter(klass): + return inspect.isclass( + klass, + ) and klass.__module__ == base_class.__module__ and issubclass( + klass, base_class, + ) and klass is not base_class + return class_filter diff --git a/homeworks/At0mn1yIvan/4/todo/runtime.py b/homeworks/At0mn1yIvan/4/todo/runtime.py new file mode 100644 index 0000000..c955fa3 --- /dev/null +++ b/homeworks/At0mn1yIvan/4/todo/runtime.py @@ -0,0 +1,52 @@ +from todo.commands import BaseCommand +from todo.custom_exceptions import UserExitException +from todo.reflection import find_classes +from todo.storage import Storage + + +def get_routes() -> dict: + """ + This function contains the dictionary of possible commands. + :return: `dict` of possible commands, with the format: `name -> class` + """ + routes = find_classes(BaseCommand) + return { + route().label: route + for _, route in routes + } + + +def perform_command(command: str) -> None: + """ + Performs the command by name. + Stores the result in `Storage()`. + :param command: command name, selected by user. + """ + command = command.lower() + routes = get_routes() + + try: + command_class = routes[command] + except KeyError: + print('Bad command, try again.') + return + + command_inst = command_class() + storage = Storage() + + try: + command_inst.perform(storage) + except UserExitException as ex: + # Handling `exit` command. + print(ex) + raise + + +def parse_user_input(): + """ + Gets the user input. + :return: `str` with the user input. + """ + commands = get_routes().keys() + message = 'Input your command: ({0}): '.format('|'.join(commands)) + return input(message) diff --git a/homeworks/At0mn1yIvan/4/todo/storage.py b/homeworks/At0mn1yIvan/4/todo/storage.py new file mode 100644 index 0000000..b60a81d --- /dev/null +++ b/homeworks/At0mn1yIvan/4/todo/storage.py @@ -0,0 +1,21 @@ +class Storage(object): # storage = Storage() + """ + Singleton storage. + + Read more about singleton design pattern: + https://stackoverflow.com/questions/6760685/creating-a-singleton-in-python + https://en.wikipedia.org/wiki/Singleton_pattern + + It is used to emulate in-memory storage. + It should be replaced with a database in a real application. + """ + + obj = None + items = None + + @classmethod + def __new__(cls, *args): + if cls.obj is None: + cls.obj = object.__new__(cls) + cls.items = [] + return cls.obj From c3f4f200727bb70522f1f8b03d769e228ed63468 Mon Sep 17 00:00:00 2001 From: At0mn1yIvan Date: Wed, 19 Oct 2022 20:21:53 +0300 Subject: [PATCH 05/12] Solution --- homeworks/At0mn1yIvan/4/.idea/.gitignore | 3 - homeworks/At0mn1yIvan/4/tests/conftest.py | 5 - .../At0mn1yIvan/4/tests/test_done_command.py | 30 ---- .../4/tests/test_representations.py | 18 --- .../At0mn1yIvan/4/tests/test_to_read_item.py | 43 ------ .../4/tests/test_undone_command.py | 30 ---- homeworks/At0mn1yIvan/4/todo/__init__.py | 0 homeworks/At0mn1yIvan/4/todo/__main__.py | 28 ---- homeworks/At0mn1yIvan/4/todo/commands.py | 131 ------------------ .../At0mn1yIvan/4/todo/custom_exceptions.py | 2 - homeworks/At0mn1yIvan/4/todo/models.py | 52 ------- homeworks/At0mn1yIvan/4/todo/reflection.py | 35 ----- homeworks/At0mn1yIvan/4/todo/runtime.py | 52 ------- homeworks/At0mn1yIvan/4/todo/storage.py | 21 --- .../inspectionProfiles/profiles_settings.xml | 0 .../{4 => 5/my_awesome_script}/.idea/misc.xml | 2 +- .../my_awesome_script}/.idea/modules.xml | 2 +- .../.idea/my_awesome_script.iml} | 4 +- .../5/my_awesome_script/.idea/workspace.xml | 30 ++++ .../tests => 5/my_awesome_script}/__init__.py | 0 .../5/my_awesome_script/__main__.py | 16 +++ .../At0mn1yIvan/5/my_awesome_script/cmnds.py | 37 +++++ .../5/my_awesome_script/tskInput.py | 15 ++ 23 files changed, 101 insertions(+), 455 deletions(-) delete mode 100644 homeworks/At0mn1yIvan/4/.idea/.gitignore delete mode 100644 homeworks/At0mn1yIvan/4/tests/conftest.py delete mode 100644 homeworks/At0mn1yIvan/4/tests/test_done_command.py delete mode 100644 homeworks/At0mn1yIvan/4/tests/test_representations.py delete mode 100644 homeworks/At0mn1yIvan/4/tests/test_to_read_item.py delete mode 100644 homeworks/At0mn1yIvan/4/tests/test_undone_command.py delete mode 100644 homeworks/At0mn1yIvan/4/todo/__init__.py delete mode 100644 homeworks/At0mn1yIvan/4/todo/__main__.py delete mode 100644 homeworks/At0mn1yIvan/4/todo/commands.py delete mode 100644 homeworks/At0mn1yIvan/4/todo/custom_exceptions.py delete mode 100644 homeworks/At0mn1yIvan/4/todo/models.py delete mode 100644 homeworks/At0mn1yIvan/4/todo/reflection.py delete mode 100644 homeworks/At0mn1yIvan/4/todo/runtime.py delete mode 100644 homeworks/At0mn1yIvan/4/todo/storage.py rename homeworks/At0mn1yIvan/{4 => 5/my_awesome_script}/.idea/inspectionProfiles/profiles_settings.xml (100%) rename homeworks/At0mn1yIvan/{4 => 5/my_awesome_script}/.idea/misc.xml (69%) rename homeworks/At0mn1yIvan/{4 => 5/my_awesome_script}/.idea/modules.xml (54%) rename homeworks/At0mn1yIvan/{4/.idea/HW4.iml => 5/my_awesome_script/.idea/my_awesome_script.iml} (68%) create mode 100644 homeworks/At0mn1yIvan/5/my_awesome_script/.idea/workspace.xml rename homeworks/At0mn1yIvan/{4/tests => 5/my_awesome_script}/__init__.py (100%) create mode 100644 homeworks/At0mn1yIvan/5/my_awesome_script/__main__.py create mode 100644 homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py create mode 100644 homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py diff --git a/homeworks/At0mn1yIvan/4/.idea/.gitignore b/homeworks/At0mn1yIvan/4/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/homeworks/At0mn1yIvan/4/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/homeworks/At0mn1yIvan/4/tests/conftest.py b/homeworks/At0mn1yIvan/4/tests/conftest.py deleted file mode 100644 index e846edf..0000000 --- a/homeworks/At0mn1yIvan/4/tests/conftest.py +++ /dev/null @@ -1,5 +0,0 @@ -import os -import sys - -BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) -sys.path.append(BASE_DIR) diff --git a/homeworks/At0mn1yIvan/4/tests/test_done_command.py b/homeworks/At0mn1yIvan/4/tests/test_done_command.py deleted file mode 100644 index 83a6927..0000000 --- a/homeworks/At0mn1yIvan/4/tests/test_done_command.py +++ /dev/null @@ -1,30 +0,0 @@ -def test_class_exists(): - from todo.commands import DoneCommand - - assert isinstance(DoneCommand, type) - - -def test_command_label_in_list(): - from todo.commands import DoneCommand - from todo.runtime import get_routes - - assert DoneCommand().label in get_routes() - - -def test_command_execution(monkeypatch): - from todo.commands import DoneCommand - from todo.runtime import perform_command - from todo.models import Storage, ToDoItem - - monkeypatch.setitem(__builtins__, 'input', lambda _: 0) - - item = ToDoItem('test') - item.done = False - - s = Storage() - s.items.clear() - s.items.append(item) - - perform_command(DoneCommand().label) - - assert item.done is True diff --git a/homeworks/At0mn1yIvan/4/tests/test_representations.py b/homeworks/At0mn1yIvan/4/tests/test_representations.py deleted file mode 100644 index 07043c8..0000000 --- a/homeworks/At0mn1yIvan/4/tests/test_representations.py +++ /dev/null @@ -1,18 +0,0 @@ -def test_to_buy_item(): - from todo.models import ToBuyItem - - item = ToBuyItem('header', 'price') - assert str(item).startswith('- ToBuy: ') - - item.done = True - assert str(item).startswith('+ ToBuy: ') - - -def test_to_do_item(): - from todo.models import ToDoItem - - item = ToDoItem('subject') - assert str(item).startswith('- ToDo: ') - - item.done = True - assert str(item).startswith('+ ToDo: ') diff --git a/homeworks/At0mn1yIvan/4/tests/test_to_read_item.py b/homeworks/At0mn1yIvan/4/tests/test_to_read_item.py deleted file mode 100644 index b1ea1e3..0000000 --- a/homeworks/At0mn1yIvan/4/tests/test_to_read_item.py +++ /dev/null @@ -1,43 +0,0 @@ -def test_class_exists(): - from todo.models import ToReadItem - - assert isinstance(ToReadItem, type) - - -def test_there_are_attributes(): - from todo.models import ToReadItem - - heading = 'test' - url = 'http://ya.ru' - item = ToReadItem(heading, url) - - assert item.heading == heading - assert item.url == url - assert item.done is False - - -def test_fabric_method(monkeypatch): - from todo.models import ToReadItem - - value = 'some input' - - monkeypatch.setitem(__builtins__, 'input', lambda _: value) - item = ToReadItem.construct() - - assert item.heading == value - assert item.url == value - assert item.done is False - - -def test_representation(): - from todo.models import ToReadItem - - heading = 'test' - url = 'http://ya.ru' - item = ToReadItem(heading, url) - - assert str(item) == '- ToRead: {} {}'.format(heading, url) - - item.done = True - - assert str(item) == '+ ToRead: {} {}'.format(heading, url) diff --git a/homeworks/At0mn1yIvan/4/tests/test_undone_command.py b/homeworks/At0mn1yIvan/4/tests/test_undone_command.py deleted file mode 100644 index b25bedf..0000000 --- a/homeworks/At0mn1yIvan/4/tests/test_undone_command.py +++ /dev/null @@ -1,30 +0,0 @@ -def test_class_exists(): - from todo.commands import UndoneCommand - - assert isinstance(UndoneCommand, type) - - -def test_command_label_in_list(): - from todo.commands import UndoneCommand - from todo.runtime import get_routes - - assert UndoneCommand().label in get_routes() - - -def test_command_execution(monkeypatch): - from todo.commands import UndoneCommand - from todo.runtime import perform_command - from todo.models import Storage, ToDoItem - - monkeypatch.setitem(__builtins__, 'input', lambda _: 0) - - item = ToDoItem('test') - item.done = True - - s = Storage() - s.items.clear() - s.items.append(item) - - perform_command(UndoneCommand().label) - - assert item.done is False diff --git a/homeworks/At0mn1yIvan/4/todo/__init__.py b/homeworks/At0mn1yIvan/4/todo/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/homeworks/At0mn1yIvan/4/todo/__main__.py b/homeworks/At0mn1yIvan/4/todo/__main__.py deleted file mode 100644 index 55f9f2c..0000000 --- a/homeworks/At0mn1yIvan/4/todo/__main__.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -Main file. Contains program execution logic. -""" - -from todo.custom_exceptions import UserExitException -from todo.runtime import parse_user_input, perform_command - - -def main(): - """ - Main method, works infinitely until user runs `exit` command. - Or hits `Ctrl+C` in the console. - """ - while True: - try: - perform_command(parse_user_input()) - except UserExitException: - break - except Exception as ex: - print('You have done something wrong!', ex) - - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - print() - print('Shutting down, bye!') diff --git a/homeworks/At0mn1yIvan/4/todo/commands.py b/homeworks/At0mn1yIvan/4/todo/commands.py deleted file mode 100644 index 330af74..0000000 --- a/homeworks/At0mn1yIvan/4/todo/commands.py +++ /dev/null @@ -1,131 +0,0 @@ - -from todo.custom_exceptions import UserExitException -from todo.models import BaseItem -from todo.reflection import find_classes - - -class BaseCommand(object): - label: str - - def perform(self, store): - raise NotImplementedError() - - -class ListCommand(BaseCommand): - label = 'list' - - def perform(self, store): - if len(store.items) == 0: - print('There are no items in the storage.') - return - - for index, obj in enumerate(store.items): - print('{0}: {1}'.format(index, str(obj))) - - -class NewCommand(BaseCommand): - label = 'new' - - def perform(self, store): - classes = self._load_item_classes() - - print('Select item type:') - for index, name in enumerate(classes.keys()): - print('{0}: {1}'.format(index, name)) - - selection = None - selected_key = None - - while True: - try: - selected_key = self._select_item(classes) - except ValueError: - print('Bad input, try again.') - except IndexError: - print('Wrong index, try again.') - else: - break - - selected_class = classes[selected_key] - print('Selected: {0}'.format(selected_class.__name__)) - print() - - new_object = selected_class.construct() - - store.items.append(new_object) - - print('Added {0}'.format(str(new_object))) - print() - return new_object - - - def _load_item_classes(self) -> dict: - # Dynamic load: - return dict(find_classes(BaseItem)) - - - def _select_item(self, classes): - selection = int(input('Input number: ')) - if selection < 0: - raise IndexError('Index needs to be >0') - return list(classes.keys())[selection] - - -class MarkCommand(object): - - def perform(self, store): - k = 0 - - for obj in store.items: - if str(obj)[0] == self.char_command: - k += 1 - if k == 0: - print("There are no {0} items in the storage.".format(self.char_command)) - return - - for index, obj in enumerate(store.items): - if str(obj)[0] == self.char_command: - print('{0}: {1}'.format(index, str(obj))) - - selected_item = self.select_item(store) - - print("{0} has been {1}\n".format(selected_item, self.operation)) - - operation = getattr(selected_item, str(self.operation), None) - assert operation is not None - operation() - - def select_item(self, store): - while True: - try: - user_selection = int(input("Input number of item: ")) - if user_selection < 0 or str(store.items[user_selection])[0] != self.char_command: - raise IndexError() - except ValueError: - print("Bad input, try again") - except IndexError: - print("Bad index, try again") - else: - break - if store.items is None: - print("There are no items in storage") - return store.items[user_selection] - - -class DoneCommand(MarkCommand, BaseCommand): - label = "done" - char_command = '-' - operation = "mark_done" - - -class UndoneCommand(MarkCommand, BaseCommand): - label = "undone" - char_command = '+' - operation = "mark_undone" - - -class ExitCommand(BaseCommand): - label = 'exit' - - def perform(self, _store): - raise UserExitException('See you next time!') diff --git a/homeworks/At0mn1yIvan/4/todo/custom_exceptions.py b/homeworks/At0mn1yIvan/4/todo/custom_exceptions.py deleted file mode 100644 index 5e8963c..0000000 --- a/homeworks/At0mn1yIvan/4/todo/custom_exceptions.py +++ /dev/null @@ -1,2 +0,0 @@ -class UserExitException(Exception): - """We use this exception when user wants to exit.""" diff --git a/homeworks/At0mn1yIvan/4/todo/models.py b/homeworks/At0mn1yIvan/4/todo/models.py deleted file mode 100644 index cac7010..0000000 --- a/homeworks/At0mn1yIvan/4/todo/models.py +++ /dev/null @@ -1,52 +0,0 @@ -class BaseItem(object): - def __init__(self, heading): - self.heading = heading - self.done = False #TODO: make sure we can use it... - - def __repr__(self): - return self.__class__.__name__ - - def mark_done(self): - self.done = True - - def mark_undone(self): - self.done = False - - def __str__(self): - return "{0} {1}".format('+' if self.done else '-', self.__repr__()) - - @classmethod - def construct(cls): - raise NotImplementedError() - - -class ToDoItem(BaseItem): - def __str__(self): - return '{0}: {1}'.format( - super().__str__(), - self.heading, - ) - - @classmethod - def construct(cls): - heading = input('Input heading: ') - return cls(heading) - - -class ToBuyItem(BaseItem): - def __init__(self, heading, price): - super().__init__(heading) - self.price = price - - def __str__(self): - return '{0}: {1} for {2}'.format( - super().__str__(), - self.heading, - self.price, - ) - - @classmethod - def construct(cls): - heading = input('Input heading: ') - price = input('Input price: ') - return cls(heading, price) diff --git a/homeworks/At0mn1yIvan/4/todo/reflection.py b/homeworks/At0mn1yIvan/4/todo/reflection.py deleted file mode 100644 index 40dcfbf..0000000 --- a/homeworks/At0mn1yIvan/4/todo/reflection.py +++ /dev/null @@ -1,35 +0,0 @@ -import inspect -import sys - - -def find_classes(base_class) -> tuple: - """ - Finds all subclasses of a class inside module. - - :param base_class: Base class to search children. - :return: tuple of subclasses - """ - return inspect.getmembers( - sys.modules[base_class.__module__], - _reflect_filter(base_class), - ) - - -def _reflect_filter(base_class): - """ - Reflection is used to load modules dynamically. - - This method is complex. It does some dark magic. - How is it even possible to understand it? - - :param base_class: Target base class - :return: function to filter only subclasses of `base_class` - """ - - def class_filter(klass): - return inspect.isclass( - klass, - ) and klass.__module__ == base_class.__module__ and issubclass( - klass, base_class, - ) and klass is not base_class - return class_filter diff --git a/homeworks/At0mn1yIvan/4/todo/runtime.py b/homeworks/At0mn1yIvan/4/todo/runtime.py deleted file mode 100644 index c955fa3..0000000 --- a/homeworks/At0mn1yIvan/4/todo/runtime.py +++ /dev/null @@ -1,52 +0,0 @@ -from todo.commands import BaseCommand -from todo.custom_exceptions import UserExitException -from todo.reflection import find_classes -from todo.storage import Storage - - -def get_routes() -> dict: - """ - This function contains the dictionary of possible commands. - :return: `dict` of possible commands, with the format: `name -> class` - """ - routes = find_classes(BaseCommand) - return { - route().label: route - for _, route in routes - } - - -def perform_command(command: str) -> None: - """ - Performs the command by name. - Stores the result in `Storage()`. - :param command: command name, selected by user. - """ - command = command.lower() - routes = get_routes() - - try: - command_class = routes[command] - except KeyError: - print('Bad command, try again.') - return - - command_inst = command_class() - storage = Storage() - - try: - command_inst.perform(storage) - except UserExitException as ex: - # Handling `exit` command. - print(ex) - raise - - -def parse_user_input(): - """ - Gets the user input. - :return: `str` with the user input. - """ - commands = get_routes().keys() - message = 'Input your command: ({0}): '.format('|'.join(commands)) - return input(message) diff --git a/homeworks/At0mn1yIvan/4/todo/storage.py b/homeworks/At0mn1yIvan/4/todo/storage.py deleted file mode 100644 index b60a81d..0000000 --- a/homeworks/At0mn1yIvan/4/todo/storage.py +++ /dev/null @@ -1,21 +0,0 @@ -class Storage(object): # storage = Storage() - """ - Singleton storage. - - Read more about singleton design pattern: - https://stackoverflow.com/questions/6760685/creating-a-singleton-in-python - https://en.wikipedia.org/wiki/Singleton_pattern - - It is used to emulate in-memory storage. - It should be replaced with a database in a real application. - """ - - obj = None - items = None - - @classmethod - def __new__(cls, *args): - if cls.obj is None: - cls.obj = object.__new__(cls) - cls.items = [] - return cls.obj diff --git a/homeworks/At0mn1yIvan/4/.idea/inspectionProfiles/profiles_settings.xml b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/inspectionProfiles/profiles_settings.xml similarity index 100% rename from homeworks/At0mn1yIvan/4/.idea/inspectionProfiles/profiles_settings.xml rename to homeworks/At0mn1yIvan/5/my_awesome_script/.idea/inspectionProfiles/profiles_settings.xml diff --git a/homeworks/At0mn1yIvan/4/.idea/misc.xml b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/misc.xml similarity index 69% rename from homeworks/At0mn1yIvan/4/.idea/misc.xml rename to homeworks/At0mn1yIvan/5/my_awesome_script/.idea/misc.xml index d5637fc..d56657a 100644 --- a/homeworks/At0mn1yIvan/4/.idea/misc.xml +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/misc.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/4/.idea/modules.xml b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/modules.xml similarity index 54% rename from homeworks/At0mn1yIvan/4/.idea/modules.xml rename to homeworks/At0mn1yIvan/5/my_awesome_script/.idea/modules.xml index 37e6459..8f193b9 100644 --- a/homeworks/At0mn1yIvan/4/.idea/modules.xml +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/4/.idea/HW4.iml b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/my_awesome_script.iml similarity index 68% rename from homeworks/At0mn1yIvan/4/.idea/HW4.iml rename to homeworks/At0mn1yIvan/5/my_awesome_script/.idea/my_awesome_script.iml index 74d515a..d0876a7 100644 --- a/homeworks/At0mn1yIvan/4/.idea/HW4.iml +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/my_awesome_script.iml @@ -1,9 +1,7 @@ - - - + diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/workspace.xml b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/workspace.xml new file mode 100644 index 0000000..1a1339e --- /dev/null +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/workspace.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + 1666188150890 + + + + \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/4/tests/__init__.py b/homeworks/At0mn1yIvan/5/my_awesome_script/__init__.py similarity index 100% rename from homeworks/At0mn1yIvan/4/tests/__init__.py rename to homeworks/At0mn1yIvan/5/my_awesome_script/__init__.py diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/__main__.py b/homeworks/At0mn1yIvan/5/my_awesome_script/__main__.py new file mode 100644 index 0000000..3995515 --- /dev/null +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/__main__.py @@ -0,0 +1,16 @@ +from tskInput import com_input + + +def main(): + try: + com_input() + except Exception as ex: + print("Something went wrong.", ex) + + +if __name__ == '__main__': + try: + main() + except KeyboardInterrupt: + print() + print('Shutting down, bye!') diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py b/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py new file mode 100644 index 0000000..9d636bf --- /dev/null +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py @@ -0,0 +1,37 @@ +import pytz +from pygments import highlight +from pygments.formatters import TerminalFormatter +from pygments.lexers import PythonLexer +from cowpy import cow +from datetime import datetime + + + +def task(action: str, text: str = None) -> None: + if action == 'help': + functions[action]() + else: + functions[action](text) + + +def highlight_(code: str) -> None: + print(highlight(code, PythonLexer(), TerminalFormatter())) + + +def cowsay_(text: str) -> None: + print(cow.milk_random_cow(text)) + + +def time_(timezone: str) -> None: + local_date = datetime.now(pytz.timezone(timezone)) + print("{0} {1}".format(local_date.date(), local_date.time())) + + +def help_() -> None: + print("EXAMPLE COMMAND:") + print(" highlight 'any text'") + print(" cowsay 'any text'") + print(" time 'Region/City'") + + +functions = {'highlight': highlight_, 'cowsay': cowsay_, 'time': time_, 'help': help_} \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py b/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py new file mode 100644 index 0000000..2a67b7d --- /dev/null +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py @@ -0,0 +1,15 @@ +import argparse +from cmnds import task, functions + + +def com_input(): + parser = argparse.ArgumentParser() + parser.add_argument("action", help="Input action.", choices=functions) + parser.add_argument("text", help="highlight 'any text' or cowsay 'any text' or time 'Region/City'.") + args = parser.parse_args() + + try: + task(args.action, args.text) + except Exception as ex: + task("help") + raise ex \ No newline at end of file From 0fdf67519dc22839d455e7a5affc0a1cefd44917 Mon Sep 17 00:00:00 2001 From: At0mn1yIvan Date: Mon, 24 Oct 2022 22:14:00 +0300 Subject: [PATCH 06/12] Solution --- .../inspectionProfiles/profiles_settings.xml | 6 ---- .../5/my_awesome_script/.idea/misc.xml | 4 --- .../5/my_awesome_script/.idea/modules.xml | 8 ----- .../.idea/my_awesome_script.iml | 8 ----- .../5/my_awesome_script/.idea/workspace.xml | 30 ------------------- 5 files changed, 56 deletions(-) delete mode 100644 homeworks/At0mn1yIvan/5/my_awesome_script/.idea/inspectionProfiles/profiles_settings.xml delete mode 100644 homeworks/At0mn1yIvan/5/my_awesome_script/.idea/misc.xml delete mode 100644 homeworks/At0mn1yIvan/5/my_awesome_script/.idea/modules.xml delete mode 100644 homeworks/At0mn1yIvan/5/my_awesome_script/.idea/my_awesome_script.iml delete mode 100644 homeworks/At0mn1yIvan/5/my_awesome_script/.idea/workspace.xml diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/inspectionProfiles/profiles_settings.xml b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2d..0000000 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/misc.xml b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/misc.xml deleted file mode 100644 index d56657a..0000000 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/modules.xml b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/modules.xml deleted file mode 100644 index 8f193b9..0000000 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/my_awesome_script.iml b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/my_awesome_script.iml deleted file mode 100644 index d0876a7..0000000 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/my_awesome_script.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/workspace.xml b/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/workspace.xml deleted file mode 100644 index 1a1339e..0000000 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/.idea/workspace.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - 1666188150890 - - - - \ No newline at end of file From cb9b631856f6c643992e0ece470736686cbb5a36 Mon Sep 17 00:00:00 2001 From: At0mn1yIvan Date: Wed, 26 Oct 2022 23:17:36 +0300 Subject: [PATCH 07/12] Solution --- homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py | 3 +-- homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py b/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py index 9d636bf..379bd4e 100644 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py @@ -6,7 +6,6 @@ from datetime import datetime - def task(action: str, text: str = None) -> None: if action == 'help': functions[action]() @@ -34,4 +33,4 @@ def help_() -> None: print(" time 'Region/City'") -functions = {'highlight': highlight_, 'cowsay': cowsay_, 'time': time_, 'help': help_} \ No newline at end of file +functions = {'highlight': highlight_, 'cowsay': cowsay_, 'time': time_, 'help': help_} # noqa: E501 diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py b/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py index 2a67b7d..a28f318 100644 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py @@ -5,11 +5,11 @@ def com_input(): parser = argparse.ArgumentParser() parser.add_argument("action", help="Input action.", choices=functions) - parser.add_argument("text", help="highlight 'any text' or cowsay 'any text' or time 'Region/City'.") + parser.add_argument("text", help="highlight 'any text'/cowsay 'any text'/time 'Region/City'") # noqa: E501 args = parser.parse_args() try: task(args.action, args.text) except Exception as ex: task("help") - raise ex \ No newline at end of file + raise ex From 62517629d14d277a75ba05d8a739fcd8764fffc5 Mon Sep 17 00:00:00 2001 From: At0mn1yIvan Date: Wed, 26 Oct 2022 23:43:17 +0300 Subject: [PATCH 08/12] Solution --- homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py | 5 +++-- homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py b/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py index 379bd4e..1953dff 100644 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py @@ -1,9 +1,10 @@ +from datetime import datetime + import pytz +from cowpy import cow from pygments import highlight from pygments.formatters import TerminalFormatter from pygments.lexers import PythonLexer -from cowpy import cow -from datetime import datetime def task(action: str, text: str = None) -> None: diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py b/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py index a28f318..974bfe1 100644 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py @@ -1,5 +1,6 @@ import argparse -from cmnds import task, functions + +from cmnds import functions, task def com_input(): From d7ca02f55527de23439874493fffce6de951b8ba Mon Sep 17 00:00:00 2001 From: Khramov Ivan <90196856+At0mn1yIvan@users.noreply.github.com> Date: Wed, 26 Oct 2022 23:49:50 +0300 Subject: [PATCH 09/12] Update __main__.py --- homeworks/At0mn1yIvan/5/my_awesome_script/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/__main__.py b/homeworks/At0mn1yIvan/5/my_awesome_script/__main__.py index 3995515..61bc2da 100644 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/__main__.py +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/__main__.py @@ -5,7 +5,7 @@ def main(): try: com_input() except Exception as ex: - print("Something went wrong.", ex) + print('Something went wrong.', ex) if __name__ == '__main__': From 344ac27793097f8fe95b8bef0902cac4483330d2 Mon Sep 17 00:00:00 2001 From: Khramov Ivan <90196856+At0mn1yIvan@users.noreply.github.com> Date: Wed, 26 Oct 2022 23:51:56 +0300 Subject: [PATCH 10/12] Update cmnds.py --- homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py b/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py index 1953dff..e73edda 100644 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py @@ -14,24 +14,24 @@ def task(action: str, text: str = None) -> None: functions[action](text) -def highlight_(code: str) -> None: +def Highlight(code: str) -> None: print(highlight(code, PythonLexer(), TerminalFormatter())) -def cowsay_(text: str) -> None: +def Cowsay(text: str) -> None: print(cow.milk_random_cow(text)) -def time_(timezone: str) -> None: +def Time(timezone: str) -> None: local_date = datetime.now(pytz.timezone(timezone)) print("{0} {1}".format(local_date.date(), local_date.time())) -def help_() -> None: +def Help() -> None: print("EXAMPLE COMMAND:") print(" highlight 'any text'") print(" cowsay 'any text'") print(" time 'Region/City'") -functions = {'highlight': highlight_, 'cowsay': cowsay_, 'time': time_, 'help': help_} # noqa: E501 +functions = {'highlight': Highlight, 'cowsay': Cowsay, 'time': Time, 'help': Help} # noqa: E501 From f079843a895fb0aa5d0ee24b91ba6fbe5578ca5b Mon Sep 17 00:00:00 2001 From: Khramov Ivan <90196856+At0mn1yIvan@users.noreply.github.com> Date: Wed, 26 Oct 2022 23:53:02 +0300 Subject: [PATCH 11/12] Update tskInput.py --- homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py b/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py index 974bfe1..68b4d97 100644 --- a/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py +++ b/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py @@ -5,12 +5,12 @@ def com_input(): parser = argparse.ArgumentParser() - parser.add_argument("action", help="Input action.", choices=functions) - parser.add_argument("text", help="highlight 'any text'/cowsay 'any text'/time 'Region/City'") # noqa: E501 + parser.add_argument('action', help='Input action.', choices=functions) + parser.add_argument('text', help="highlight 'any text'/cowsay 'any text'/time 'Region/City'") # noqa: E501 args = parser.parse_args() try: task(args.action, args.text) except Exception as ex: - task("help") + task('help') raise ex From 3b106a807b6004a1e1e4c4d380f8019c5d339906 Mon Sep 17 00:00:00 2001 From: At0mn1yIvan Date: Wed, 26 Oct 2022 23:56:12 +0300 Subject: [PATCH 12/12] Solution --- homeworks/At0mn1yIvan/5/{my_awesome_script => }/__init__.py | 0 homeworks/At0mn1yIvan/5/{my_awesome_script => }/__main__.py | 0 homeworks/At0mn1yIvan/5/{my_awesome_script => }/cmnds.py | 0 homeworks/At0mn1yIvan/5/{my_awesome_script => }/tskInput.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename homeworks/At0mn1yIvan/5/{my_awesome_script => }/__init__.py (100%) rename homeworks/At0mn1yIvan/5/{my_awesome_script => }/__main__.py (100%) rename homeworks/At0mn1yIvan/5/{my_awesome_script => }/cmnds.py (100%) rename homeworks/At0mn1yIvan/5/{my_awesome_script => }/tskInput.py (100%) diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/__init__.py b/homeworks/At0mn1yIvan/5/__init__.py similarity index 100% rename from homeworks/At0mn1yIvan/5/my_awesome_script/__init__.py rename to homeworks/At0mn1yIvan/5/__init__.py diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/__main__.py b/homeworks/At0mn1yIvan/5/__main__.py similarity index 100% rename from homeworks/At0mn1yIvan/5/my_awesome_script/__main__.py rename to homeworks/At0mn1yIvan/5/__main__.py diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py b/homeworks/At0mn1yIvan/5/cmnds.py similarity index 100% rename from homeworks/At0mn1yIvan/5/my_awesome_script/cmnds.py rename to homeworks/At0mn1yIvan/5/cmnds.py diff --git a/homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py b/homeworks/At0mn1yIvan/5/tskInput.py similarity index 100% rename from homeworks/At0mn1yIvan/5/my_awesome_script/tskInput.py rename to homeworks/At0mn1yIvan/5/tskInput.py