
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()

