Skip to content
Open

Hw_4 #86

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
22 changes: 22 additions & 0 deletions homeworks/hw_1/Загадки.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import random
# A game of riddles:

count = 0
n = 10
questions = ('Какая версия языка сейчас актуальна?', 'Какая кодировка используется в строках?',
'Какой оператор сравнения нужно использовать для работы с None и bool?', 'Сколько значений есть у bool?')
ansvers = ('Python3', 'UTF8', 'is', '2')


for i in range(n):
j = random.randint(0,3)
print(questions[j])
users_input = str(input('Введите ответ: '))
if users_input.lower() == ansvers[j].lower() :
count+=1
print("Ответ {0} верен".format(users_input))
else:
print("Ответ неверный\n")

print('Число отгаданных загадок: {0} из 10'.format(count))

66 changes: 66 additions & 0 deletions homeworks/hw_2/Array.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
class Array(object):

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

def append(self, new_arg):
self._data += (new_arg, )

def __add__(self, new):
return self._data + new._data

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

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

def __iter__(self):
return iter(self._data)

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

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

# init_test
print('Init test:')
A = Array(1, 2, 3, 4, 5)
print('Array A')
A.print()

# append_test
print('Append test:')
A.append('abc')
print('Append element "abc" to array A')
A.print()

# add_test
print('Addition test:')
B = Array(100, 200)
print('Add array (100, 200) to array A')
print(A + B)

#len_test
print('Length test:')
print('Length of last array = {0}'.format(len(A+B)))

# index_test
print('Index test:')
print('Index of element 2 in array A')
print(A.index(2))
print('Index of element 89 in array A')
print(A.index(89))

# for_test
print('For loop test:')
for arg in A:
print(arg)

# []_test
print('Indexing test:')
print('Print first element of the array A:')
print(A[0])
91 changes: 91 additions & 0 deletions homeworks/hw_3/hw_3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
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 decorator(function):
def argument_check(*args, **kwargs):
if arg_types is not None:
arguments = tuple(args) + tuple(kwargs.values())

if len(arguments) != len(arg_types):
raise ContractError("Argument count error")
else:
for index, arg_t in enumerate(arg_types):
if arg_t != Any and arg_t != type(arguments[index]):
raise ContractError("Argument type mismatch error")

if return_type is None:
pass
else:
if return_type != type(function(*args, **kwargs)) and return_type != Any:
raise ContractError("Return type error")

try:
result = function(*args, **kwargs)
except:
raise raises

return result
return argument_check
return decorator



#First example
@contract(arg_types=(int, int), return_type=int)
def add_two_numbers(first, second):
return first + second
print(add_two_numbers(1, 2))



#Second example
#add_two_numbers('a', 'b')



#Third example
#@contract(arg_types=(int, int), return_type=float, raises=(ZeroDivisionError,))
#def div(first, second):
# return first / second
#
#print(div(1, 2)) # ok
#print(div(1, 0)) # raises ZeroDisionError
#print(div(1, None)) # raises ContractError from TypeError



#Fourth example
#validates only return type, args and raises are ignored:
#@contract(return_type=int)
#def return_myself(x):
# return x
#
#print(return_myself(10))

# validation is completely disabled:
#@contract(return_type=None, arg_types=None, raises=None)
#def hello_world():
# print('Hello, World!')
#hello_world()

# return type and raises checks are disabled:
#@contract(arg_types=(str, str))
#def sum_string(x, y):
# return x+y
#print(sum_string('abc', 'def'))



#Fifth example
#@contract(arg_types=(int, Any))
#def add_two_numbers(first, second):
# return first + second
#
#print(add_two_numbers(1, 2)) # ok
#print(add_two_numbers(1, 3.4)) # ok
#print(add_two_numbers(2.1, 1)) # raises ContractError
Binary file added homeworks/hw_4/__MACOSX/hw5/._hw5.md
Binary file not shown.
27 changes: 27 additions & 0 deletions homeworks/hw_4/hw5/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# TODO CLI App


## Legend

This application is used for our internal needs.
It was developed a long time ago by an unknown developer.

It works fine. But there are several things we would like to improve.


## Running

To run this app follow these steps:

1. `cd hw5`
2. `python3 -m todo` ([docs](https://docs.python.org/3/using/cmdline.html#cmdoption-m))
3. Enjoy!


## Testing

If you don't know what you are doing, skip this step.

0. Make sure that you are in this folder, near `README.md`
1. `pip install pytest`
2. `pytest`
53 changes: 53 additions & 0 deletions homeworks/hw_4/hw5/hw5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
## Теория

### Полезности

- `datetime`: https://docs.python.org/3/library/datetime.html
- `collections`: https://docs.python.org/3/library/collections.html
- `itertools`: https://docs.python.org/3/library/itertools.html
- `functools`: https://docs.python.org/3/library/functools.html
- `os`: https://docs.python.org/3/library/os.html
- `sys`: https://docs.python.org/3/library/sys.html
- `re`: https://docs.python.org/3/library/re.html
- `argparse`: https://docs.python.org/3/library/argparse.html

### Imports

- modules: https://docs.python.org/3/tutorial/modules.html
- Решаем проблему цикличных импортов: https://stackoverflow.com/questions/5748946/pythonic-way-to-resolve-circular-import-statements
- Откуда можно импортировать: https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH и https://stackoverflow.com/questions/19917492/how-to-use-pythonpath и http://www.johnny-lin.com/cdat_tips/tips_pylang/path.html
- Relative imports vs absolute: https://stackoverflow.com/questions/28400690/python3-correct-way-to-import-relative-or-absolute и http://pulkitgoyal.com/absolute-relative-imports


## Практика

Данное задание будет построено в формате ролевой игры, чтобы показать реальность подобных задач, ситуаций и подходов.

### Легенда

В компании, куда вы пришли работать, есть для вас первая задача.
Все сотрудники пользуются внутренней системой ведения учета задач.
Но вот проблема, в ней есть некоторые моменты, которые нужно улучшить.

Никто точно не помнит, кто написал программу и когда.
К сожаению, спросить, как она работает, некого.
Более того, сами сотрудники не могут посмотреть, что там в коде, потому что они не программисты.
Но они слышали, что там есть сложные части, а есть какие-то простые.
Вроде бы код написан нормально, но документации к нему не сохранилось.
Только инструкция по запуску.

### Технические требования

Менеджер подготовил для вас техническое задание, какие фичи он хотел бы увидеть:

- Необходимо добавить всем задачам визуальный статус готовности. Он должен выглядеть так: `+ ToDo: ...`, где `+` или `-` - статус готовности (`+` - выполнено, `-` - невыполнено), `ToDo` - название типа задачи и `...` - атрибуты задачи
- Необходимо реализовать команду `done`, которая бы отмечала задачи выполнеными (все задачи по-умолчанию невыполнены)
- Необходимо реализовать команду `undone`, которая бы отмечала задачи невыполнеными
- Необходимо добавить новый тип задачи: `ToReadItem`, у которой было бы два поля: `heading` и `url`. Следовательно: что прочитать и где

### Проверка результатов (для продвинуты, необязательно)

Старый разработчик был большим фанатом [TTD](https://en.wikipedia.org/wiki/Test-driven_development), и он успел перед своим уходом написать тесты, как должы работать все те новые требования.
Но закончить проект не успел.

В качестве проверки будем использовать их.
5 changes: 5 additions & 0 deletions homeworks/hw_4/hw5/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)
31 changes: 31 additions & 0 deletions homeworks/hw_4/hw5/tests/test_done_command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
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 ToDoItem
from todo.storage import Storage

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/hw_4/hw5/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/hw_4/hw5/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)
31 changes: 31 additions & 0 deletions homeworks/hw_4/hw5/tests/test_undone_command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
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 ToDoItem
from todo.storage import Storage

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.
Loading