TelenkovDmitry 6 bulan lalu
induk
melakukan
e48f8d63da

+ 67 - 0
courses/python_oop/exception/exception_1.py

@@ -0,0 +1,67 @@
+
+class Wallet:
+
+    def __init__(self, currency, balance):
+
+        if not isinstance(currency, str):
+            raise TypeError("Неверный тип валюты")
+        elif len(currency) != 3:
+            raise NameError("Неверная длина названия валюты")
+        elif not currency.isupper():
+            raise ValueError("Название должно состоять только из заглавных букв")
+        self.currency = currency
+        self.balance = balance
+
+    def __eq__(self, value):
+        if not isinstance(value, Wallet):
+            raise TypeError(f"Wallet не поддерживает сравнение с {value}")
+        elif self.currency != value.currency:
+            raise ValueError("Нельзя сравнить разные валюты")
+        else:
+            return self.balance == value.balance
+        
+    def __add__(self, value):
+        if not isinstance(value, Wallet):
+            raise ValueError("Данная операция запрещена")
+        elif self.currency != value.currency:
+            raise ValueError("Данная операция запрещена")
+        else:
+            return Wallet(self.currency, self.balance + value.balance)
+
+    def __sub__(self, value):
+        if not isinstance(value, (Wallet)):
+            raise ValueError("Данная операция запрещена")
+        elif self.currency != value.currency:
+            raise ValueError("Данная операция запрещена")
+        else:
+            return Wallet(self.currency, self.balance - value.balance)
+
+
+def main():
+
+    '''
+    wallet1 = Wallet('USD', 50)
+    wallet2 = Wallet('RUB', 100)
+    wallet3 = Wallet('RUB', 150)
+    wallet4 = Wallet(12, 150)  # исключение TypeError('Неверный тип валюты')
+    wallet5 = Wallet('qwerty', 150)  # исключение NameError('Неверная длина названия валюты')
+    wallet6 = Wallet('abc', 150)  # исключение ValueError('Название должно состоять только из заглавных букв')
+    print(wallet2 == wallet3)  # False
+    print(wallet2 == 100)  # TypeError('Wallet не поддерживает сравнение с 100')
+    print(wallet2 == wallet1)  # ValueError('Нельзя сравнить разные валюты')
+    wallet7 = wallet2 + wallet3
+    print(wallet7.currency, wallet7.balance)  # печатает 'RUB 250'
+    wallet2 + 45  # ValueError('Данная операция запрещена')
+    '''
+
+    '''
+    try:
+        int('sdfawsdf')
+    except ValueError:
+        print('!!!!')
+    '''
+
+
+
+if __name__ == '__main__':
+    main()

+ 43 - 0
courses/python_oop/exception/exception_2.py

@@ -0,0 +1,43 @@
+
+def excp_1():
+    print(1)
+    print(2)
+    try:
+        print(3)
+        print(1/0)
+    except ZeroDivisionError:
+        print('Ошибка деления на ноль!')
+    print(4)
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Распространение исключений
+
+def first_func():
+    print('Начало работы функции first_func')
+    try:
+        second_func()
+    except Exception as ex:
+        print(f'Внимание! Обработано исключение: {ex}')
+    print('Конец работы функции first_func')
+
+def second_func():
+    print('Начало работы функции second_func')
+    third_func()
+    print('Конец работы функции second_func')
+
+def third_func():
+    print('Начало работы fird_func')
+    1/0
+    print('Конец работы функции third_func')
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Обработка исключений
+
+
+def main():
+    # excp_1()
+    first_func()
+
+
+if __name__ == '__main__':
+    main()

+ 105 - 0
courses/python_oop/exception/exception_3.py

@@ -0,0 +1,105 @@
+# Обработка исключений
+
+
+
+def exc_1():
+    try:
+        int('hello')
+        1/0
+    except ValueError:
+        print('error ValueError')
+
+#
+def exc_2():
+    try:
+        1/0
+    except Exception as e:
+        print(e)
+    finally:    # выполняется всегда
+        print('finally!!!')
+
+def exc_3():
+    try:
+        1/1
+    # except (KeyError, IndexError):
+    except Exception as e:
+        print('Exception!!!', e)
+    else:   # отрабатывает когда в try нет исключения
+        print('try else!!! Исключения не состоялось!')
+    finally:
+        print('Еще и finally можно запилить!!!')
+
+def exc_4():
+    try:
+        a = int(input())
+        b = int(input())
+        print(f"Результат деления a на b: {a/b}")
+    except (ValueError, ZeroDivisionError):
+        print('Введите корректные значения')
+
+def exc_5():
+    try:
+        a = int(input())
+        b = int(input())
+        print(f"Результат деления a на b: {a/b}")
+    except ValueError:
+        print('Введите целое число')
+    except ZeroDivisionError:
+        print('Делитель не должен быть равен нулю')
+
+def exc_6():
+    try:
+        file = open('pentagon_secrets.txt', 'r')
+        print(file.read())
+    except FileNotFoundError:
+        print('Эх, не судьба тайны пентагона узнать')
+
+def func(phrase):
+    func(phrase)
+
+def exc_7():
+    try:
+        func('Это рекурсия, детка!')
+    except RecursionError:
+        print('Кто-то должен остановить это безумие')
+
+
+class CustomButton:
+    
+    def __init__(self, text, **kwargs):
+        self.text = text
+        for key, value in kwargs.items():
+            setattr(self, key, value)
+
+    def config(self, **kwargs):
+        for key, value in kwargs.items():
+            setattr(self, key, value)
+    
+    def click(self):
+        try:
+            self.command()
+        except AttributeError:
+            print('Кнопка не настроена')
+        except TypeError:
+            print('Кнопка сломалась')
+
+def main():
+    # exc_1()
+    # exc_2()
+    # exc_4()
+    # exc_5()
+    # exc_6()
+    # exc_7()    
+    
+    '''
+    door = CustomButton('text', size='180x70', color='red', material='oak')
+    print(door.size, door.color, door.material, sep=', ')
+    door.config(new_attr='value')
+    print(door.size, door.color, door.material, door.new_attr, sep=', ')
+    door.config(new_attr='new_value')
+    print(door.size, door.color, door.material, door.new_attr, sep=', ')
+    '''
+    
+
+if __name__ == '__main__':
+    main()

+ 195 - 0
courses/python_oop/exception/raise.py

@@ -0,0 +1,195 @@
+
+def raise_1():
+    try:
+        # {}['k'] # ошибка key error
+        [1, 2, 3][14] # ошибка index error
+    except (KeyError, IndexError) as error:
+        print(f'Logging error: {repr(error)}')
+        raise TypeError("raise TypeError!!!") from None
+    except ZeroDivisionError as err:
+        print('ZeroDevisionError')
+        print(f'Logging error: {err} {repr(err)}')
+        
+
+def raise_2():
+    a = TypeError("Ошибка типа")
+    print(a.args)
+    raise a
+
+def raise_3():
+    try:
+        raise ValueError('ошибка значения')
+    except ValueError as first:
+        try:
+            raise TypeError('ошибка типа')
+        except TypeError as second:
+            raise Exception('Большое исключение') from first
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+def function_1():
+    try:
+        x = 1/0
+        print('The end')
+    except ZeroDivisionError:
+        print("Can't divide by zero")
+        raise ValueError("Oops, something went wrong")
+    
+def function_2():
+    try:
+        function_1()
+    except ValueError as e:
+        print("ValueError cauth:", e)
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class Customer:
+
+    def __init__(self, name, balance=0):
+        self.name = name
+        self.balance= balance
+
+    @staticmethod
+    def check_type(value):
+        if not isinstance(value, (int, float)):
+            raise TypeError('Банк работает только с числами')
+
+    def withdraw(self, value):
+        Customer.check_type(value)
+        if self.balance < value:
+            raise ValueError('Сумма списания превышает баланс')
+        else:
+            self.balance -= value
+
+    def deposit(self, value):
+        Customer.check_type(value)
+        self.balance += value
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+def sum_numbers(numbers: list[int]):
+    if not isinstance(numbers, list):
+        raise TypeError("Аргумент numbers должен быть списком")
+    if not numbers:
+        raise ValueError("Пустой список")
+    for elem in numbers:
+        if not isinstance(elem, (int, float)):
+            raise TypeError('Неправильный тип элемента')
+    return sum(numbers)
+
+
+
+def main():
+
+    for value in (True, (1, 2, 3), {1: 'hello'}, {1, 2, 3}):
+        try:
+            result = sum_numbers(value)
+        except TypeError as error:
+            print(error)
+
+    try:
+        result = sum_numbers([])
+    except ValueError as error:
+        print(error)
+
+    try:
+        sum_numbers([1, 'hello', 2, 3])
+    except TypeError as error:
+        print(error)
+
+    try:
+        sum_numbers([1, 2, 3, 4, 5, [1, 2, 3]])
+    except TypeError as error:
+        print(error)
+
+    try:
+        sum_numbers([1, 2, 3, 4, 5, {1, 2, 3}])
+    except TypeError as error:
+        print(error)
+
+    try:
+        sum_numbers([1, 2, 3, 4, 5, (1, 2, 3)])
+    except TypeError as error:
+        print(error)
+
+    assert sum_numbers([1, 2, 3, 4, 5]) == 15
+    assert sum_numbers([1, 2, 3, 4, 5.0]) == 15.0
+
+
+    # raise_1()
+    # raise_2()
+    # raise_3()
+    # function_2()
+
+    # cus = Customer('user, 110')
+    # cus.check_type()
+
+    # my_list = [1, 2, 'asfadsf']
+    # empty_list = []
+
+    # sum_numbers(my_list)
+    # sum_numbers(empty_list)
+
+    '''
+    assert Customer.check_type(2) is None, 'Метод check_type не должен ничего возращать'
+    assert Customer.check_type(2.5) is None, 'Метод check_type не должен ничего возращать'
+
+    for i in ['hello', [1, 2, 3], dict(), set()]:
+        try:
+            Customer.check_type(i)
+        except TypeError as error:
+            print(error)
+        else:
+            raise TypeError(f'Метод check_type должен вызывать ошибку если передать {i}')
+
+    bob = Customer('Bob Odenkirk')
+    assert bob.balance == 0
+    assert bob.name == 'Bob Odenkirk'
+    try:
+        bob.deposit('hello')
+    except TypeError as error:
+        print(error)
+    else:
+        raise ValueError("Нельзя вносить на счет баланса строку")
+
+    try:
+        bob.deposit([])
+    except TypeError as error:
+        print(error)
+    else:
+        raise ValueError("Нельзя вносить на счет баланса список")
+
+    bob.deposit(200)
+    assert bob.balance == 200
+
+    try:
+        bob.withdraw(300)
+    except ValueError as e:
+        print(e)
+    else:
+        raise ValueError("Проверьте списание при превышении лимита")
+
+    bob.withdraw(150)
+    assert bob.balance == 50
+
+    terk = Customer('Terk', 1000)
+    assert terk.name == 'Terk'
+    assert terk.balance == 1000
+    terk.withdraw(999)
+    assert terk.balance == 1, 'Не списались деньги, проверяйте списание'
+    terk.withdraw(1)
+    assert terk.balance == 0, 'Не списались деньги, проверяйте списание'
+
+    try:
+        terk.withdraw(1)
+    except ValueError as e:
+        print(e)
+    else:
+        raise ValueError("Проверьте списание при превышении лимита")
+    assert terk.balance == 0
+    '''
+
+
+if __name__ == '__main__':
+    main()
+

+ 166 - 0
courses/python_oop/exception/user_exception.py

@@ -0,0 +1,166 @@
+
+class MyException(Exception):
+    """this is my excpetion"""
+    
+    def __init__(self, *args):
+        if args:
+            self.massage = args[0]
+        else:
+            self.message = None
+
+    def __str__(self):
+        print('str called')
+        if self.message:
+            return f"MyException {self.message}"
+        else:
+            return "MyException is empty"
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class SnakeExceptionBase(Exception):
+    """Основной класс ошибок змейки"""
+    pass
+
+class SnakeBorderException(SnakeExceptionBase):
+    """Ошибка соприкосновения змеи со стенкой"""
+    pass
+
+class SnakeTailException(SnakeBorderException):
+    """Соприкосновение змеи и тела"""
+    pass
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class UserNotFoundError(Exception):
+    pass
+
+users = {
+        "alice": {"name": "Alice Smith", "email": "alice@example.com"},
+        "bob": {"name": "Bob Johnson", "email": "bob@example.com"},
+        "jack": {"name": "Jack Wild", "email": "jack_wild@example.com"}
+    }
+
+def get_user(username):
+    if username not in users.keys():
+        raise UserNotFoundError("User not found")
+    return users[username]['name']
+
+def get_user_test():
+    try:
+        username = get_user('bob')
+    except UserNotFoundError as e:
+        print(e)
+    else:
+        print(username)
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class NegativeDepositError(Exception):
+    pass
+
+class InsufficientFundsError(Exception):
+    pass
+
+class BankAccount:
+
+    def __init__(self, balance):
+        self.balance = balance
+
+    def deposit(self, value):
+        if value < 0:
+            raise NegativeDepositError("Нельзя пополнить счет отрицательным значением")
+        self.balance += value
+        
+    def withdraw(self, value):
+        if value > self.balance:
+            raise InsufficientFundsError("Недостаточно средств для снятия")
+        self.balance -= value
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class PasswordInvalidError(Exception):
+    pass
+
+class PasswordLengthError(PasswordInvalidError):
+    pass
+
+class PasswordContainUpperError(PasswordInvalidError):
+    pass
+
+class PasswordContainDigitError(PasswordInvalidError):
+    pass
+
+
+class User:
+
+    def __init__(self, username, password=None):
+        self.username = username
+        self.password = password
+
+    def set_password(self, value):
+        up_str = ''
+        digit_str = ''
+
+        if len(value) < 8:
+            raise PasswordLengthError("Пароль должен быть не менее 8 символов")
+        
+        for sim in value:
+            if sim.isupper():
+                up_str += sim
+            if sim.isdigit():
+                digit_str += sim
+        if not up_str:
+            raise PasswordContainUpperError('Пароль должен содержать хотя бы одну заглавную букву')
+        if not digit_str:
+            raise PasswordContainDigitError('Пароль должен содержать хотя бы одну цифру')
+
+        self.password = value
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+def func_1():
+    # raise MyException('asdf', 1, 2, 3)
+    raise MyException()
+
+    # try:
+    #     raise MyException('asdf', 1, 2, 3)
+    # except MyException:
+    #     print('done')
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+def main():
+    # get_user_test()
+    # func_1()
+
+    assert issubclass(PasswordInvalidError, Exception)
+    assert issubclass(PasswordLengthError, PasswordInvalidError)
+    assert issubclass(PasswordContainUpperError, PasswordInvalidError)
+    assert issubclass(PasswordContainDigitError, PasswordInvalidError)   
+
+    user = User("johndoe")
+
+    try:
+        user.set_password("weakpwd")
+    except PasswordLengthError as e:
+        print(e)
+
+    try:
+        user.set_password("strongpassword8")
+    except PasswordContainUpperError as e:
+        print(e)
+
+    try:
+        user.set_password("Safepassword")
+    except PasswordContainDigitError as e:
+        print(e)
+
+    user.set_password("SecurePass123")
+    assert user.password == 'SecurePass123'
+
+
+
+if __name__ == "__main__":
+    main()

+ 55 - 0
courses/python_oop/inheritance/slots.py

@@ -0,0 +1,55 @@
+from timeit import timeit
+
+class Point:
+
+    def __init__(self, x, y):
+        self.x = x
+        self.y = y
+
+
+class PointSlots:
+
+    # Теперь __dict__ не будет и нельзя будет создавать новые атрибуты.
+    __slots__ = {'x', 'y'}
+
+    def __init__(self, x, y):
+        self.x = x
+        self.y = y
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class Person:
+
+    __slots__ = {'first_name', 'last_name', 'age'}
+
+    def __init__(self, first_name, last_name, age):
+        self.first_name = first_name
+        self.last_name = last_name
+        self.age = age
+
+    def __str__(self):
+        return f"{self.first_name} {self.last_name} is {self.age} years old"
+
+
+def make_cl1():
+    s = Point(3, 4)
+    s.x = 100
+    s.x
+    del s.x
+
+def make_cl2():
+    s = PointSlots(3, 4)
+    s.x = 100
+    s.x
+    del s.x
+
+
+
+
+def main():
+    print(timeit(make_cl1))
+    print(timeit(make_cl2))
+
+
+if __name__ == '__main__':
+    main()

+ 49 - 0
courses/python_oop/inheritance/slots_2.py

@@ -0,0 +1,49 @@
+
+class Rectangle:
+
+    __slots__ = '__width', 'height'
+
+    def __init__(self, a, b):
+        self.width = a
+        self.height = b
+
+    @property
+    def width(self):
+        return self.__width
+    
+    @width.setter
+    def width(self, value):
+        print("Setter called")
+        self.__width = value
+
+    @property
+    def perimetr(self):
+        return (self.height + self.width) * 2
+
+    @property
+    def area(self):
+        return self.height * self.width
+
+# У класса наследника будет атрибут __dict__ если не задать атрибут __slots__
+class Square(Rectangle):
+    
+    # этот slots расширяет имена родительского класса
+    __slots__ = 'color'
+
+    def __init__(self, a, b, color):
+        super().__init__(a, b)
+        self.color = color
+
+
+def main():
+    a = Rectangle(3, 4)
+    b = Rectangle(5, 6)
+
+    print(b.perimetr, b.area)
+
+
+    s = Square(3, 6, 'red')
+    # print(s.__dict__)
+
+if __name__ == '__main__':
+    main()

+ 155 - 0
courses/python_oop/inheritance/slots_3.py

@@ -0,0 +1,155 @@
+
+class Device:
+
+    __slots__ = '_name', '_location', '_status'
+
+    def __init__(self, name, location, status='ON'):
+        self._name = name
+        self.location = location
+        self.status = status
+    
+    @property
+    def name(self):
+        return self._name
+
+    @property
+    def location(self):
+        return self._location
+    
+    @location.setter
+    def location(self, value):
+        self._location = value
+    
+    @property
+    def status(self):
+        return self._status
+    
+    @status.setter
+    def status(self, value):
+        self._status = value
+
+    def turn_on(self):
+        self.status = 'ON'
+
+    def turn_off(self):
+        self.status = 'OFF'
+
+class Light(Device):
+
+    __slots__ = '_brightness', '_color'
+
+    def __init__(self, name, location, brightness, color):
+        super().__init__(name, location)
+        self.brightness = brightness
+        self._color = color
+        
+    @property
+    def brightness(self):
+        return self._brightness
+    
+    @brightness.setter
+    def brightness(self, value):
+        self._brightness = value
+    
+    @property
+    def color(self):
+        return self._color
+
+
+class Thermostat(Device):
+
+    __slots__ = '_current_temperature', '_target_temperature'
+
+    def __init__(self, name, location, current_temperature, target_temperature):
+        super().__init__(name, location)
+        self.current_temperature = current_temperature
+        self.target_temperature = target_temperature
+
+    @property
+    def current_temperature(self):
+        return self._current_temperature
+    
+    @current_temperature.setter
+    def current_temperature(self, value):
+        self._current_temperature = value
+
+    @property
+    def target_temperature(self):
+        return self._target_temperature
+    
+    @target_temperature.setter
+    def target_temperature(self, value):
+        self._target_temperature = value
+
+
+class SmartTV(Device):
+
+    __slots__ = '_channel'
+
+    def __init__(self, name, location, channel):
+        super().__init__(name, location)
+        self.channel = channel
+
+    @property
+    def channel(self):
+        return self._channel
+    
+    @channel.setter
+    def channel(self, value):
+        self._channel = value
+
+def main():
+
+    '''
+    dev = Device('robot-bobot', 'Moscow', 'on')
+    print(dev.name)
+
+    light = Light('light-bobot', 'Moscow', 'on', 70, 'red')
+    print(light.name)
+    print(light.brightness)
+    print(light.color)
+    '''
+
+    device1 = Device('Устройство 1', 'Гостиная')
+    assert device1.name == 'Устройство 1'
+    assert device1._name == 'Устройство 1'
+    assert device1.location == 'Гостиная'
+    assert device1._location == 'Гостиная'
+    assert device1.status == 'ON'
+    assert device1._status == 'ON'
+
+    device1.turn_off()
+    assert device1.status == 'OFF'
+    device1.location = 'Кухня'
+    assert device1.location == 'Кухня'
+    assert device1._location == 'Кухня'
+    device1.turn_on()
+    assert device1.status == 'ON'
+
+    light1 = Light('Лампа', 'Гостиная', 50, 'белый')
+    light1.name == 'Лампа'
+    light1.location == 'Гостиная'
+    light1.status == 'ON'
+    light1.brightness == '50'
+    light1.color == 'белый'
+
+    light1.turn_off()
+    light1.status == 'OFF'
+
+    thermostat_1 = Thermostat('Термометр', 'Балкон', 10, 15)
+    thermostat_1.name == 'Термометр'
+    thermostat_1.location == 'Балкон'
+    thermostat_1.status == 'ON'
+    thermostat_1.current_temperature == 10
+    thermostat_1.target_temperature == 15
+
+    tv = SmartTV('Samsung', 'Спальня', 20)
+    tv.name == 'Термометр'
+    tv.location == 'Балкон'
+    tv.status == 'ON'
+    tv.channel == 20
+
+    print('GOOD')
+
+if __name__ == '__main__':
+    main()