Skip to content
Open

HW8 #118

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 lesson-8/helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
def int_input(prompt):
return typed_input(prompt, int)


def str_input(prompt):
return typed_input(prompt, str)


def float_input(prompt):
return typed_input(prompt, float)


def typed_input(prompt, input_type):
value = None
while True:
try:
value = input_type(input(prompt))
except ValueError:
print('Input error')
continue
break
return value
42 changes: 42 additions & 0 deletions lesson-8/task-1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import re


def get_max_month_days(month):
if month == 2:
return 28
elif month in [4, 6, 9, 11]:
return 30
return 31


class Date:
def __init__(self, date_str):
if self.validate(date_str):
self.date = date_str
else:
raise ValueError

def __str__(self):
return self.date

@classmethod
def parse(cls, date_str):
# return map(int, date_str.split('-'))
date_split = date_str.split('-')
return int(date_split[0]), int(date_split[1]), int(date_split[2])

@staticmethod
def validate(date_str):
if not re.match(r'\d{1,2}-\d{1,2}-\d{4}', date_str):
return False
day, month, year = Date.parse(date_str)
has_errors = month not in range(1, 12)
has_errors |= day not in range(1, get_max_month_days(month))
return not has_errors


try:
print(Date.parse('46-4-2341'))
print(Date.validate('46-4-2341'))
except ValueError:
print('Date error')
24 changes: 24 additions & 0 deletions lesson-8/task-2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from helper import int_input


class MyZeroDivisionExtension(Exception):
pass


class Number:
def __init__(self, num: int):
self.num = num

def __truediv__(self, other):
if other.num == 0:
raise MyZeroDivisionExtension('Division by zero')
return self.num/other.num


number1 = Number(int_input('Enter number 1: '))
number2 = Number(int_input('Enter number 2: '))

try:
print('Div: ', number1 / number2)
except MyZeroDivisionExtension as e:
print(e.__class__.__name__, ':', e)
37 changes: 37 additions & 0 deletions lesson-8/task-3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import re


class InvalidListValueException(Exception):
pass


class IntList:
def __init__(self):
self._elements = []

@staticmethod
def validate(value):
return re.match(r'\d+', value)

def append(self, value):
if not self.validate(value):
raise InvalidListValueException('Input value must be number')
self._elements.append(int(value))

def __str__(self):
return ' '.join(map(str, self._elements))


int_list = IntList()
while True:
input_string = input('Enter number or stop: ')
if input_string.lower() == 'stop':
break

try:
int_list.append(input_string)
except InvalidListValueException as e:
print(e.__class__.__name__, ':', e)

print('Result:')
print(int_list)
54 changes: 54 additions & 0 deletions lesson-8/task-4_6.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import datetime
import random
import string

from warehouse import models

BRANDS_LIST = ['Canon', 'LG', 'Philips', 'Xiaomi']


def generate_model_name():
return '%s (%s)' % (
random.choice(BRANDS_LIST),
random.choices(string.ascii_uppercase + string.digits, k=8)
)


def generate_equip():
cls = random.choice(models.Equipment.__subclasses__())
return cls(
model=generate_model_name(),
year=random.randint(2000, datetime.date.today().year),
is_new=random.choice([True, False, True])
)


equipments = [generate_equip() for i in range(10)]

eq_1 = equipments[0]
eq_2 = equipments[1]

deparment_1 = models.Department('Department 1')
deparment_2 = models.Department('Department 2')
warehouse = models.Warehouse('Main')

warehouse.append_list(equipments)
print('==== WAREHOUSE BALANCE ====')
warehouse.balance()
print('==================')
warehouse.append(eq_1)

warehouse.move_equipment(eq_1, deparment_1)
warehouse.move_equipment(eq_2, deparment_1)
warehouse.move_equipment(eq_1, deparment_2)
print('========= DEPARTMENT 1 BALANCE =========')
deparment_1.balance()
print('==================')

try:
warehouse.move_equipments(models.Printer.__name__, deparment_2, 2)
except AssertionError as e:
print('На складе нет столько техники')
print('========= DEPARTMENT 2 BALANCE =========')
deparment_2.balance()
print('==================')
56 changes: 56 additions & 0 deletions lesson-8/task-7.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import unittest


class Complex:
def __init__(self, real, imagine):
assert isinstance(real, int)
assert isinstance(imagine, int)
self.real = real
self.imagine = imagine

def __add__(self, other):
return Complex(self.real + other.real, self.imagine + other.imagine)

def __mul__(self, other):
return Complex(
real=(self.real * other.real - self.imagine * other.imagine),
imagine=(self.real * other.imagine + self.imagine * other.real)
)

def __str__(self):
if self.imagine == 0:
return str(self.real)

return '(%s%s%sj)' % (
self.real,
'+' if self.imagine > 0 else '-',
abs(self.imagine) if self.imagine != 1 else ''
)


class ComplexTest(unittest.TestCase):
def test_str(self):
complex_1 = Complex(1, 2)
complex_2 = complex(1, 2)
self.assertEqual(str(complex_1), str(complex_2))

def test_add(self):
c_1_1 = Complex(1, 2)
c_1_2 = Complex(2, 1)

c_2_1 = complex(1, 2)
c_2_2 = complex(2, 1)

self.assertEqual(str(c_1_1 + c_1_2), str(c_2_1 + c_2_2))

def test_mul(self):
c_1_1 = Complex(3, 1)
c_1_2 = Complex(8, 4)

c_2_1 = complex(3, 1)
c_2_2 = complex(8, 4)

self.assertEqual(str(c_1_1 * c_1_2), str(c_2_1 * c_2_2))


unittest.main()
Empty file added lesson-8/warehouse/__init__.py
Empty file.
143 changes: 143 additions & 0 deletions lesson-8/warehouse/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import random


class Department:
def __init__(self, name: str):
assert len(name) > 0
self.name = name
self._storage = []
self._counts = {cls.__name__: 0 for cls in Equipment.__subclasses__()}

def append(self, equipment):
assert issubclass(equipment.__class__, Equipment)
if not self.find_in_storage(equipment):
self._storage.append(equipment)
self._counts[equipment.__class__.__name__] += 1
else:
print('Техника уже на складе')

def append_list(self, equipments):
for equipment in equipments:
self.append(equipment)

def remove(self, equipment):
assert issubclass(equipment.__class__, Equipment)
if self.find_in_storage(equipment):
self._storage.remove(equipment)
self._counts[equipment.__class__.__name__] -= 1
return True
return False

def find_in_storage(self, equipment):
assert issubclass(equipment.__class__, Equipment)
return next((x for x in self._storage if x == equipment), None)

def get_all(self, equipment_type):
# return [x for x in self._storage if x.__class__ == equipment_type]
for x in self._storage:
if x.__class__.__name__ == equipment_type:
yield x

def balance(self):
for cls, cnt in self._counts.items():
print(f'{cls}: {cnt}')


class Warehouse(Department):

def move_equipment(self, equipment, department):
if self.remove(equipment):
department.append(equipment)
else:
print('На складе нет необходимой техники')

def back_equipment(self, equipment, department):
if department.remove(equipment):
self.append(equipment)
else:
print('В отделении нет необходимой техники')

def move_equipments(self, equipment_type, deparmet, count):
assert self._counts[equipment_type] >= count
for equipment in self.get_all(equipment_type):
self.move_equipment(equipment, deparmet)


class Equipment:
def __init__(self, model: str, year: int, is_new: bool):
self.serial = random.randint(10000, 999999) # серийный номер
self.model = model # модель
self.year = year # год выпуска
self.is_new = is_new # новый/бу
self.is_broken = False

def __str__(self):
return f'{self.serial} {self.model} {self.year}'

def broke(self):
print('Упс! Устройство сломалось')
self.is_broken = True

def repair(self):
self.is_broken = False
self.is_new = False

def action(self): # действие устройства
if random.randint(0, 100) < 10:
self.broke()
return True

def __eq__(self, other):
return isinstance(other, self.__class__) and other.serial == self.serial


class Printer(Equipment):
def __init__(self, model, year, is_new):
super().__init__(model, year, is_new)
self._ink = {'r': 0, 'g': 0, 'b': 0} # черлила

def refuel(self):
self._ink = {'r': 100, 'g': 100, 'b': 100}

def action(self):
if not self.can_print():
self._empty_ink_signal()
return False
# при печати принтер тратит бумагу
for k, ink in self._ink.items():
self._ink[k] = random.randint(0, ink - 10) if ink - 10 > 0 else 0
return super().action()

def can_print(self):
ret = True
for ink in self._ink:
ret &= ink > 0
return ret

def _empty_ink_signal(self):
print('Кончились чернила, необходимо замена')


class Fax(Equipment):
def __init__(self, model, year, is_new):
super().__init__(model, year, is_new)
self._papers = 100

def action(self):
if self._papers == 0:
print('Закончилась бумага')
return False
self._papers -= random.randint(1, self._papers)
return super().action()


class Scaner(Equipment):
def action(self):
print('Сканирование...')
return super().action()


class Xerox(Equipment):
def action(self):
print('Ксерокопирование...')
return super().action()