Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions homeworks/SoldatovDaniil/2/hw2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class Array(object):

def __init__(self, *args):
self._data = tuple(args)

def append(self, elem):
self._data = (*self._data, elem)

def __add__(self, other):
return Array(*(self._data + other._data))

def __radd__(self, other):
return Array(*(other._data + self._data))

def show(self):
print(self._data)

def __len__(self):
return len(self._data)

def index(self, elem):
if elem in self._data:
return self._data.index(elem)
else:
return -1

def __getitem__(self, index):
return self._data[index]


a = Array(1, 2, 123, 56)
b = Array(1, 1000)

a.show()
b.show()

a += b
a = a + b
b = a + Array(0)

a.show()
b.show()
print(a[3])

for i in a:
print(i)
37 changes: 37 additions & 0 deletions homeworks/SoldatovDaniil/3/hw3.py
Original file line number Diff line number Diff line change
@@ -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 decorated_contract(func):
def wrapped(*args, **kwargs):
if arg_types is not None:
allArgs = tuple(args + tuple(kwargs.values()))
for index in range(len(arg_types)):
if arg_types[index] != Any:
if not isinstance(allArgs[index], arg_types[index]):
raise ContractError("ArgsType Error")
try:
result = func(*args, **kwargs)
except (Exception if raises is None or Any in raises else raises) as ex:
raise ex
except Exception as ex:
raise ContractError from ex
if return_type is not None:
if not isinstance(result, return_type):
raise ContractError("ReturnType Error")
return result
return wrapped
return decorated_contract


@contract(arg_types=(int, int), return_type=float, raises=(ZeroDivisionError,))
def div(one, two):
return one / two


print(div(1, 234.5))
5 changes: 5 additions & 0 deletions homeworks/SoldatovDaniil/4/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -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)
30 changes: 30 additions & 0 deletions homeworks/SoldatovDaniil/4/tests/test_done_command.py
Original file line number Diff line number Diff line change
@@ -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
18 changes: 18 additions & 0 deletions homeworks/SoldatovDaniil/4/tests/test_representations.py
Original file line number Diff line number Diff line change
@@ -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: ')
43 changes: 43 additions & 0 deletions homeworks/SoldatovDaniil/4/tests/test_to_read_item.py
Original file line number Diff line number Diff line change
@@ -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)
30 changes: 30 additions & 0 deletions homeworks/SoldatovDaniil/4/tests/test_undone_command.py
Original file line number Diff line number Diff line change
@@ -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
Empty file.
28 changes: 28 additions & 0 deletions homeworks/SoldatovDaniil/4/todo/__main__.py
Original file line number Diff line number Diff line change
@@ -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!')
128 changes: 128 additions & 0 deletions homeworks/SoldatovDaniil/4/todo/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@

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):
x = 0

for obj in store.items:
if str(obj)[0] == self.char_command:
x += 1
if x == 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")
except IndexError:
print("Bad index")
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!')
2 changes: 2 additions & 0 deletions homeworks/SoldatovDaniil/4/todo/custom_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class UserExitException(Exception):
"""We use this exception when user wants to exit."""
Loading