Задачи на
Python

Python: задачи и решения
Приводим варианты решений задач к урокам курса «Программирование на Python» и даем соответствующие комментарии. Также обратите внимание, что решение большинства задач дополнительно разобрано в видео формате. Ссылки на соответствующие видео приведены ниже.
А ЕЩЕ У НАС ЕСТЬ КЛАССНЫЙ ЗАДАЧНИК ПО PYTHON!
Close
Подробнее о списках, кортежах, словарях, множествах и других типах данных в Python можно прочитать в Уроке 2 "Программирование на Python: Типы данных".

Задача 1.1

Условие
1. Создать произвольный список
2. Добавить новый элемент типа str в конец списка
3. Добавить новый элемент типа int на место с индексом
4. Добавить новый элемент типа list в конец списка
5. Добавить новый элемент типа tuple на место с индексом
6. Получить элемент по индексу
7. Удалить элемент
8. Найти число повторений элемента списка
Решение - Интерактивный режим
# 1. Создаем список
>>> lst = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

# 2. Добавляем элемент с типом str в конец списка
>>> lst.append('Строка')
#[1, 1, 1, 1, 1, 1, 1, 1, 1, 'Строка']

# 3. Вставляем элемент со значением 189 на место с индексом 4
>>> lst[4] = 189
# Результат: [1, 1, 1, 1, 189, 1, 1, 1, 1, 1, 'Строка']

# 4. Добавляем вложенный список ['a', 'b', 'a', 'hello']
lst.append(['a', 'b', 'a', 'hello'])
# Результат: [1, 1, 1, 1, 189, 1, 1, 1, 1, 1, 'Строка', ['a', 'b', 'a', 'hello']]

# 5. Вставляем кортеж со значением (1, 6, 89) на место с индексом -3 (3-й элемент с конца списка)
>>> lst[-3] = (1, 6, 89)
# Результат: [1, 1, 1, 1, 189, 1, 1, 1, 1, (1, 6, 89), 'Строка', ['a', 'b', 'a', 'hello']]

# 6. Получаем значение элемента с индексом 0
>>> lst[0]
1
# Получаем значение элемента с индексом -1(последний элемент списка)
>>> lst[-1]
['a', 'b', 'a', 'hello']

# 7. Удаляем элемент со значением 189
>>> lst.remove(189)
# Результат: [1, 1, 1, 1, 1, 1, 1, 1, (1, 6, 89), 'Строка', ['a', 'b', 'a', 'hello']]

# 8. Считаем количество элементов в списке со значением 1
>>> lst.count(1)
8

Задача 1.2

Условие
Получите первый и последний элемент списка
Решение - Интерактивный режим
>>> lst = ['Нулевой элемент', 'One', 2, 3, 4, (5, 5, 5)]
>>> lst[0]
'Нулевой элемент'
>>> lst[-1]
(5, 5, 5)

Задача 1.3

Условие
Поменяйте значения переменных a и b местами
Решение - Интерактивный режим
>>> a = 100
>>> b = 'Строка'
>>> a, b = b, a
>>> a
'Строка'
>>> b
100

Задача 1.4

Условие
Проверить, есть ли в последовательности дубликаты
Решение - Интерактивный режим
# Создаем список с дубликатами lst
>>> lst = [0, 0, 1, 2, 3, 4, 5, 5, 6, 7]

# На основе списка создаем множество st
# Помним про основное свойство множеств - они не могут содержать дубликатов
# Поэтому если lst содержит дубликаты, то при создании множества на его основе дубликаты будут удалены
>>> st = set(lst)

# А значит количество элементов в списке и во множестве будет различаться
# Сравниваем количество элементов с помощью встроенного метода len()
>>> len(st) == len(lst)
False
# Длины не равны, значит в изначальном списке были дубликаты

Задача 1.5

Условие
1. Создать произвольный словарь
2. Добавить новый элемент с ключом типа str и значением типа int 
3. Добавить новый элемент с ключом типа кортеж(tuple) и значением типа список(list)
4. Получить элемент по ключу
5. Удалить элемент по ключу
6. Получить список ключей словаря
Решение - Интерактивный режим
# 1. Создаем словарь
dct = {1: 'value_1', 2: 'value_2', 3: 'value_3'}

# 2. Добавляем в словарь новый элемент с ключом 'str_key' и значением 12345
dct['str_key'] = 12345
# Содержимое словаря: {1: 'value_1', 2: 'value_2', 3: 'value_3', 'str_key': 12345}

# 3. Добавляем в словарь новый элемент с ключом ('it', 'is', 'tuple') и значением [11, 22, 'list_value', 33, {1, 2, 3}]
dct[('it', 'is', 'tuple')] = [11, 22, 'list_value', 33, {1, 2, 3}]
# Содержимое словаря: {1: 'value_1', 2: 'value_2', 3: 'value_3', 'str_key': 12345, ('it', 'is', 'tuple'): [11, 22, 'list_value', 33, {1, 2, 3}]}

# 4. Получаем элемент словаря по ключу 'str_key'
# Способ 1: Напрямую - в случае отсутствия ключа формируется исключение
item_by_key_v1 = dct['str_key']
# Значение item_by_key_v1 равно 12345
# Способ 2: Через функцию get() - в случае отсутствия ключа возвращается дефолтное значение 'No item'
item_by_key_v2 = dct.get('str_key', 'No item')
# Значение item_by_key_v2 так же равно 12345

# 5. Удаляем элемент с ключом '2' из словаря
item_deleted = dct.pop(2, 'No item')
# Содержимое словаря: {1: 'value_1', 3: 'value_3', 'str_key': 12345, ('it', 'is', 'tuple'): [11, 22, 'list_value', 33, {1, 2, 3}]}

# 6. Получаем ключи словаря
# Возвращаемое значение: dict_keys([1, 3, 'str_key', ('it', 'is', 'tuple')])
keys = dct.keys()

Задача 1.6

Условие
1. Создать множество(set) 
2. Создать неизменяемое множество(frozenset) 
3. Выполнить операцию объединения созданных множеств
4. Выполнить операцию пересечения созданных множеств 
Решение
# 1. Создаем изменяемое множество
st = {'it', 'is', 'set', 1}

# 2. Создаем неизменяемое множество
frozen_st = frozenset({'it', 'is', 'frozen', 'set', 2})

# 3. Выполняем операцию объединения созданных множеств
# Результатом объединения будет множество, содержащее все элементы обоих множеств(без дубликатов)
union = st | frozen_st
# Результат: {'frozen', 1, 2, 'set', 'it', 'is'}

# 4. Выполняем операцию пересечения созданных множеств
# Результатом пересечения будет множество, содержащее элементы, присутствующие одновременно в обоих множествах
intersection = st & frozen_st
# Результат: {'it', 'set', 'is'}

Еще задачи по теме


Решаем задачи и отвечаем на вопросы по теме "Списки": работаем с типом данных list

Специфика типа данных словарь (dict) в Python, характеристики. Примеры использования словарей, задачи с решениями.

Специфика типа данных кортеж (tuple) в Python, методы, операции. Примеры использования кортежей, задачи с решениями.

Специфика типа данных множества (set) в Python, методы, операции. Примеры использования множеств, задачи с решениями.

В данном уроке разбираемся с основными составляющими функции в Python: аргументы, тело, возвращаемое значение. Изучаем структуру и синтаксис условного оператора if..elif..else. Учимся писать циклы for и while. Решаем задачи.

С теоретической частью можно познакомиться в Уроке 3 "Программирование на Python: Функции, условные выражения и циклы".

Также смотрите разбор практической части Урока 3 "Программирование на Python: Функции, условные выражения и циклы".

Задача 2.1

Условие
Создать функцию calc(a, b, operation). Описание входных параметров:
1. Первое число
2. Второе число
3. Действие над ними:
   1) + Сложить
   2) - Вычесть
   3) * Умножить
   4) / Разделить
   5) В остальных случаях функция должна возвращать "Операция не поддерживается"
Решение - IDE
def calc(a, b, operation):
    # Задаем дефолтное значение возвращаемого результата
    result = 'Операция не поддерживается'

    if operation == '+':
        result = a + b
    elif operation == '-':
        result = a - b
    elif operation == '*':
        result = a * b
    elif operation == '/':
        # Проверка деления на ноль
        if b is not 0:
            result = a / b
        else:
            result = 'Деление на 0!'

    # Возвращаем результат выполнения функции
    return result


if __name__ == '__main__':
    # Проверяем корректные значения
    print(calc(30, 15, '+'))
    print(calc(30, 15, '-'))
    print(calc(30, 15, '*'))
    print(calc(30, 15, '/'))
    # Проверяем проверку деления на ноль
    print(calc(30, 0, '/'))
    # Проверяем неподдерживаемую операцию
    print(calc(30, 15, '%'))

Задача 2.2

Условие
Напишите программу, которая будет выводить нечетные числа из списка и остановится, если встретит число 139
Решение - IDE
#  Функция, которая проверяет входной параметр на четность
def even(num):
    # Возвращаем True, если остаток от деления на 2 равен нулю
    return num % 2 == 0


if __name__ == '__main__':
    lst = [1, 34, 78, 345, 111, 8, 5, 34, 9, 3, 139, 56, 2, 67, 69, 90]

    # В цикле перебираем элементы вышесозданного списка
    for item in lst:
        # Если текущий элемент равен 139, то прерываем цикл
        if item == 139:
            break
        # Выводим элемент, если он не является четным
        if not even(item):
            print(item)

Задача 2.3

Условие
Создайте список [ 18, 14, 10, 6, 2 ]  с помощью функции range()
Решение - IDE
lst = []

# Пробегаемся циклом for по последовательности, которую формирует функция range()
# Начало диапазона: 18
# Конец диапазона: 1(обратите внимание, что 1 не включается в итоговую последовательность)
# Шаг: -4(обратный шаг - двигаемся в сторону уменьшения значений)
for item in range(18, 1, -4):
    lst.append(item)

print(lst)

Задача 2.4

Условие
Дан список lst = [11, 5, 8, 32, 15, 3, 20, 132, 21, 4, 555, 9, 20]. 
Необходимо вывести элементы, которые одновременно 1) меньше 30 и 2) делятся на 3 без остатка. Все остальные элементы списка необходимо просуммировать и вывести конечный результат.
Решение - IDE
# Задаем константы для значений, заданных в условии
MEDIAN = 30
DIV_NUM = 3

# Создаем список
lst = [11, 5, 8, 32, 15, 3, 20, 132, 21, 4, 555, 9, 20]

# Задаем начальное значение переменной для суммы элементов
sm = 0

# Поочередно перебираем элементы списка
for item in lst:
    # Проверяем, что
    # 1) Текущий элемент меньше 30
    # 2) Остаток от деления текущего элемента на 3 равен 0
    if (item < MEDIAN) and (item % DIV_NUM == 0):
        print(item)
    # Добавляем элемент к сумме, если условие не выполнено
    else:
        sm += item

# Выводим конечную сумму
print('Sum: ', sm)
Вывод в консоль
15
3
21
9
Sum:  787

Задача 2.5

Условие
Написать функцию month_to_season(), которая принимает 1 аргумент - номер месяца - и возвращает название сезона, к которому относится этот месяц. 
Например, передаем 2, на выходе получаем 'Зима'. 
Решение - IDE

# Имя функции: month_to_season
# Параметр: month
def month_to_season(month):

    # Создание словаря для хранения информации о сезонах
    # Ключ: кортеж(tuple) из номеров входящих в сезон месяцов
    # Значение: строка(str)-название сезона
    season_ranges = {
        (12, 1, 2): 'Winter',
        (3, 4, 5): 'Spring',
        (6, 7, 8): 'Summer',
        (9, 10, 11): 'Autumn'
    }
    # Создание переменной для возвращаемого значения функции
    season = None

    # Цикл, в котором по очереди перебираются пары ключ-значение(номера месяцев - сезон) из словаря
    for key, value in season_ranges.items():
        # Если значение входного параметра(номер месяца) входит в состав ключа(пример ключа - (3, 4, 5))
        if month in key:
            # То присваиваем возвращаемой переменной season название сезона
            season = value
            # Останавливаем цикл
            break
            
    # Возвращаем название сезона
    return season


# Проверяем работу функции
print(month_to_season(1))
print(month_to_season(5))
print(month_to_season(8))
print(month_to_season(9))
print(month_to_season(12))
print(month_to_season(999))
Вывод в консоль
Winter
Spring
Summer
Autumn
Winter
None

Еще задачи по теме


Особенности и структура условных выражений в Python. Полные и неполные условные выражения, примеры задач с решениями.

Задачи по циклам в Python: for, while. Синтаксис, особенности выхода из циклов, вложенные циклы.

Функции, их типы, причины применения. Аргументы и параметры, разновидности. Примеры использования и задачи с решениями.

В данном уроке учимся выполнять основные действия над строковым типом данных в Python: создание, экранирование, конкатенация и умножение, срезы, форматирование, строковые методы. Решаем задачи.

С теоретической частью можно познакомиться в Уроке 4 "Программирование на Python: Работа со строками".

Также смотрите разбор практической части Урока 4 "Программирование на Python: Работа со строками"".

Задача 3.1

Условие
Дана следующая строка: ‘Сидел барсук в своей норе и ел картошечку пюре’

1. Создайте данную строку
2. Получите ее длину
3. Проведите операцию сложения со строкой ‘.’
4. Проверьте, входит ли подстрока ‘ре’ в заданную строку
5. Посчитайте количество вхождений подстроки ‘ре’
6. Получите предпоследний символ строки
7. Получите все символы с нечетными индексами
8. Определите, сколько слов в строке
Решение - Интерактивный режим
# 1. Создаем строку
>>> my_str = 'Сидел барсук в своей норе и ел картошечку пюре'

# 2. Получаем длину строки с помощью встроенного метода len()
>>> len(my_str)
46

# 3. Выполняем конкатенацию строк
>>> my_str + '.'
'Сидел барсук в своей норе и ел картошечку пюре.'

# 4. Определяем вхождение подстроки 'ре'
>>> 'ре' in my_str
True

# 5. Определяем количество вхождений подстроки 'ре'
>>> my_str.count('ре')
2

# 6. Получаем предпоследний символ строки
>>> my_str[-2]
'р'

# 7. Получаем элементы с нечетными индексами
# Для этого выполняем срез, начиная с элемента с индексом 1 по конец строки с шагом 2
>>> my_str[1::2]
'ие асквсойнр  лкроек юе'

# 8. Определяем количество слов в строке
# Для этого считаем количество пробелов и прибавляем 1
>>> my_str.count(' ') + 1
9

Задача 3.2

Условие
Дана строка: ‘пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете.’

1. Начните строку с заглавной буквы, если она находится в нижнем регистре.
2. Найдите индекс вхождения подстроки ‘сопровождать’.
3. Замените вхождение подстроки ‘сопровождать’ на ‘поддерживать’.
4. Разбейте предложение на части по запятым. Соедините части обратно, снова добавив запятые между частями.
Решение - Интерактивный режим
# 1. Создаем строку
>>> my_str = 'пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете.'

# 2. Проверяем регистр строки и делаем первую букву заглавной, если регистр нижний
>>> if my_str.islower(): my_str.capitalize()
... 
'Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете.'

# 3. Ищем индекс вхождения подстроки 'сопровождать'
# Вариант 1: Используем метод find() - строковый метод
>>> my_str.find('сопровождать')
26
# Вариант 2: Используем метод index() - метод для работы с любыми последовательностями
>>> my_str.index('сопровождать')
26

# 4. Заменяем подстроку 'сопровождать' на 'поддерживать'
>>> my_str.replace('сопровождать', 'поддерживать')
'пишите код так, как будто поддерживать его будет склонный к насилию психопат, который знает, где вы живете.'

# 5. Разбиваем строку на подстроки по разделителю ',' и сохраняем подстроки в список
>>> lst = my_str.split(',')
>>> lst
['пишите код так', ' как будто сопровождать его будет склонный к насилию психопат', ' который знает', ' где вы живете.']

# Соединяем полученные ранее подстроки обратно
>>> ','.join(lst)
'пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете.'

Задача 3.3

Условие
Дано имя файла. Необходимо вывести его расширение.
Решение - IDE
# Импортируем стандартный модуль re для работы с регулярными выражениями
import re

# Создаем константу для имени файла, которое будет использовать для тестов
FILENAME = 'folder1/folder2/file.ext'


# Вариант решения 1 - пользуемся срезами
def extention_slice(filename):
    # Находим индекс точки
    point_pos = filename.find('.')
    # Возвращаем срез начиная с позиции после точки и до конца имени файла
    return filename[point_pos + 1:]


# Вариант решения 2 - используем функцию partition()
def extention_part(filename):
    # С помощью метода partition() разбиваем имя файла на 3 части
    # В качестве разделителя используем символ '.'
    # Метод partition() возвращает кортеж из 3 элеметов
    # Возвращаем 3-й элемент
    return filename.partition('.')[2]


# Вариант решения 3 - пользуемся регулярными выражениями
def extention_regex(filename):
    # Формируем регулярное выражение для поиска расширения:
    # \. - ищем символ точки в строке
    # .+$ - после точки ищем любые символы вплоть до конца строки
    # (.+$) - скобками формируем группу(это необходимо, чтобы получить не точку с расширением, а только само расширение)
    regex = r'\.(.+$)'
    # Обращаемся к модулю re и вызываем для него метод search для поиска подстроки по регулярному выражению
    # Из результата берем группу с индексом 1 
    # Это часть подстроки, которая подходит под выражение в скобках (например, 'ext')
    # Группа с индексом 0 - это полная подстрока, подходящая под регулярное выражение(например, '.ext')
    return re.search(regex, filename)[1]


# Тесты
if __name__ == '__main__':
    print(extention_slice(FILENAME))
    print(extention_part(FILENAME))
    print(extention_regex(FILENAME))
Вывод в консоль
ext
ext
ext

Задача 3.4

Условие
Сложите цифры целого числа.
Решение - с IDE
NUM = 12345


# Вариант решения 1 - пользуемся циклом for
def sum_for(num):
    # Инициализируем переменную для суммы
    s = 0
    # Преобразуем число в строку
    # В цикле перебираем символу полученной строки
    for item in str(num):
        # Каждый символ переводим в число и добавляем к сумме
        s = s + int(item)
    # Возвращаем конечную сумму
    return s


# Вариант решения 2 - используем генераторы списков
def sum_list(num):
    # Создаем список с помощью генератора
    # Конечные элементы списка переводим в числа
    lst = [int(item) for item in str(num)]
    # С помощью встроенной функции sum() находим сумму элементов списка
    return sum(lst)


# Тесты
if __name__ == '__main__':
    print(sum_for(NUM))
    print(sum_list(NUM))
Вывод в консоль
15
15

Задача 3.5

Условие
Замените заданное количество вхождений подстроки.
Решение - IDE
STR = '01101011101011'


# Тесты
if __name__ == '__main__':
    # Заменяем 1 ноль на единицу
    print(STR.replace('1', '0', 1))
    # Заменяем 5 нулей на единицы
    print(STR.replace('1', '0', 5))
    # Заменяем все нули на единицы(значение по-умолчанию)
    print(STR.replace('1', '0'))
    # Заменяем 9 нулей на единицы(все присутствующие единицы)
    print(STR.replace('1', '0', 9))
    # Заменяем 10 нулей на единицы(количество единиц больше, чем есть в строке)
    print(STR.replace('1', '0', 10))
Вывод в консоль
00101011101011
00000000101011
00000000000000
00000000000000
00000000000000

Задача 3.6

Условие
Выяснить, является ли строка палиндромом. 
Решение - IDE
# Список из нескольких строк для тестирования работы функции check_if_palindrome()
TESTS = ['Аргентина манит негра',
         'аргентина манит негра',
         'Манит Аргентина негра']


# Функция, которая проверяет, является ли переданная строка string палиндромом
def check_if_palindrome(string):
    # Для упрощения процесса проверки удаляем пробелы между словами
    # И переводим строку в нижний регистр
    prepared_str = string.replace(' ', '').lower()
    # Используем срез с обратным шагом, чтобы перевернуть строку задом наперед
    # Если строка равна своей перевернутой копии
    if prepared_str == prepared_str[::-1]:
        # Возвращаем логическое True
        return True
    else:
        # Возвращаем логическое False
        return False


if __name__ == '__main__':
    # Прогоняем в цикле все тестовые строки из списка
    # Для каждой строки вызываем функцию, выполняем проверку и печатаем результат
    for item in TESTS:
        print('Строка является палиндромом:', check_if_palindrome(item))
Вывод в консоль
Строка является палиндромом: True
Строка является палиндромом: True
Строка является палиндромом: False

Задача 3.7

Условие
Дана строка из двух слов. Поменяйте слова местами. 
Решение - IDE
def swap_words(string):
    # Формируем список из слов строки
    lst = string.split(' ')
    # Меняем порядок слов на обратный
    lst.reverse()
    # Соединяем слова в предложение через пробелы и возвращаем полученное значение
    return ' '.join(lst)


if __name__ == '__main__':
    print(swap_words('идет снег'))
    print(swap_words('идет снег давно'))
Вывод в консоль
снег идет
давно снег идет

Еще задачи по теме


Строки как тип данных в Python. Основные методы и свойства строк. Примеры работы со строками, задачи с решениями.

4. Модули и пакеты

В данном уроке рассматриваем модули и пакеты из стандартной библиотеки Python и репозитория PyPI. Разбираемся с командами для импорта: import и from..import. Учимся выполнять абсолютный и относительный импорт. Настраиваем виртуальные пространства venv. Создаем собственные модули.

С теоретической частью можно познакомиться в Уроке 5 "Программирование на Python: Модули и пакеты". Рекомендуем также посмотреть разбор практической части Урока 5 "Программирование на Python: Модули и пакеты".

Задание 4.1

Условие
Изучите содержимое и импортируйте модуль this.py
Решение - IDE
# Данный модуль относится к Стандартной библиотеке
# И при импорте выводит в консоль так называемый Дзен Python
import this
Вывод в консоль
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Задание 4.2

Условие
1. Найдите пакет http(относится к Стандартной библиотеке), изучите модули, из которых он состоит.
2. Импортируйте модуль client из пакета http
3. Воспользуйтесь функционалом импортированного модуля:
    1. Создайте HTTP соединение по адресу www.google.com
    2. Отправьте GET запрос по адресу выше
    3. Проверьте ответ на отправленный запрос
Решение - Интерактивный режим
>>> import http
# Вызываем справку по пакету http
>>> help('http')
Help on package http:

NAME
    http

MODULE REFERENCE
    https://docs.python.org/3.7/library/http
    
    The following documentation is automatically generated from the Python
    source files.  It may be incomplete, incorrect or include features that
    are considered implementation detail and may vary between Python
    implementations.  When in doubt, consult the module reference at the
    location listed above.

# Как мы можем заметить, данный пакет состоит из 4 модулей
PACKAGE CONTENTS
    client
    cookiejar
    cookies
    server
...........................
Решение - IDE
# 2. Импортируем модуль client из пакета http
# Модуль client позволяет отправлять и обрабатывать HTTP запросы к веб-серверу
from http import client


if __name__ == '__main__':
    # 3.1. Создаем соединение по адресу 'www.google.com'
    # Для этого обращаемся к модулю client
    # И вызываем конструктор класса HTTPConnection()
    connection = client.HTTPConnection('www.google.com')
    # 3.2. Отправляем GET запрос к корневой странице веб-сервера
    connection.request('GET', '/')
    # 3.3. Получаем ответ на наш запрос
    res = connection.getresponse()
    # Из полного ответа достаем интересующую нас веб-страницу(ее HTML код)
    page = res.read()
    print(page)
Пример HTML страницы
HTML код и отображение в браузере полученной страницы

Задание 4.3

Условие
Выполните следующие действия:
1. Изучите сайт репозитория пакетов PyPI (https://pypi.org/)
2. Запустите менеджер пакетов pip, изучите уже установленные модули.
3. Создайте виртуальное окружение через консоль.
4. Активируйте созданное окружение, установите любой из пакетов(например, requests), деактивируйте окружение.
5. Создайте виртуальное окружение через PyCharm.
6. Активируйте созданное окружение, установите пакет wget.
7. Воспользуйтесь функционалом пакета wget:
    1) Импортируйте данный пакет
    2) Скачайте с его помощью файл
Решение - Терминал/Консоль
# 2
# Обращаемся к менеджеру пакетов pip и вызываем команду list
# Она позволяет просмотреть модули и пакеты, которые глобально установлены в системе
$ pip3 list
Package            Version
------------------ --------
atomicwrites       1.3.0
attrs              19.1.0
behave             1.2.6
certifi            2019.3.9
importlib-metadata 0.19
itsdangerous       1.1.0
Jinja2             2.11.2
MarkupSafe         1.1.1
six                1.12.0
urllib3            1.25.2
uuid               1.30
zipp               0.5.2

# 3
# Создаем виртуальное окружение в папке demo_venv
$ python3 -m venv demo_venv

# Содержимое папки с виртуальным окружением
$ ls demo_venv
bin		
include		
lib		
pyvenv.cfg

# 4
# Активируем свежесозданное виртуальное окружение
# Далее работаем в рамках активированного окружения demo_venv
$ source demo_venv/bin/activate

# Устанавливаем пакет requests с помощью менеджера pip
(demo_venv)  $ pip3 install requests
Collecting requests
...
Successfully installed certifi-2020.4.5.2 chardet-3.0.4 idna-2.9 requests-2.23.0 urllib3-1.25.9

# Проверяем, что пакет установился (requests 2.23.0)
(demo_venv) $ pip3 list
Package    Version   
---------- ----------
certifi    2020.4.5.2
chardet    3.0.4     
idna       2.9       
pip        19.2.3    
requests   2.23.0    
setuptools 41.2.0    
urllib3    1.25.9   

# Деактивируем окружение
(demo_venv) $ deactivate
проект с виртуальным окружением в IDE PyCharm
5. Создаем проект с виртуальным окружением в IDE PyCharm
Вкладка Terminal в IDE PyCharm
6.1. Переходим во вкладку Terminal - окружение venv уже активировано
Установка модуля внутри терминала IDE PyCharm
6.2. Устанавливаем модуль wget
Решение - IDE PyCharm
# 7.1
# Импортируем модуль wget
import wget

if __name__ == '__main__':
    # 7.2
    # Создаем переменную для хранения ссылки на картинку
    url = 'https://m.dom-eda.com/uploads/images/catalog/item/dfc9a3e974/3cbf3bd41c_1000.jpg'
    # Обращаемся к модулю wget и вызываем метод download() 
    # Метод download() скачивает файл по ссылке и возвращает имя скачанного файла
    filename = wget.download(url)

Задание 4.4

Условие
Стандартная библиотека. Модуль calendar.

Выполните следующие действия:
   1. Изучите справку для модуля calendar
   2. Импортируйте модуль calendar
   3. Найдите расположение файла модуля calendar и изучите его содержимое
   4. Получите список доступных атрибутов модуля calendar
   5. С помощью модуля calendar узнайте, является ли 2027 год високосным
   6. С помощью модуля calendar узнайте, каким днем недели был день 25 июня 1995 года
   7. Выведите в консоль календарь на 2023 год
Решение - Интерактивный режим
# 1. Изучите справку для модуля calendar
>>> help('calendar')
Help on module calendar:

NAME
    calendar - Calendar printing functions

MODULE REFERENCE
    https://docs.python.org/3.7/library/calendar
    
    The following documentation is automatically generated from the Python
    source files.  It may be incomplete, incorrect or include features that
    are considered implementation detail and may vary between Python
    implementations.  When in doubt, consult the module reference at the
    location listed above.

DESCRIPTION
    Note when comparing these calendars to the ones printed by cal(1): By
 
....

# 2. Импортируйте модуль calendar
>>> import calendar

# 3. Найдите расположение файла модуля calendar и изучите его содержимое
>>> calendar.__file__
'/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/calendar.py'

# 4. Получите список доступных атрибутов модуля calendar
>>> dir(calendar)
['Calendar', 'EPOCH', 'FRIDAY', 'February', 'HTMLCalendar', 'IllegalMonthError', 'IllegalWeekdayError', 'January', 'LocaleHTMLCalendar', 'LocaleTextCalendar', 'MONDAY', 'SATURDAY', 'SUNDAY', 'THURSDAY', 'TUESDAY', 'TextCalendar', 'WEDNESDAY', '_EPOCH_ORD', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_colwidth', '_locale', '_localized_day', '_localized_month', '_spacing', 'c', 'calendar', 'datetime', 'day_abbr', 'day_name', 'different_locale', 'error', 'firstweekday', 'format', 'formatstring', 'isleap', 'leapdays', 'main', 'mdays', 'month', 'month_abbr', 'month_name', 'monthcalendar', 'monthlen', 'monthrange', 'nextmonth', 'prcal', 'prevmonth', 'prmonth', 'prweek', 'repeat', 'setfirstweekday', 'sys', 'timegm', 'week', 'weekday', 'weekheader']

# 5. С помощью модуля calendar узнайте, является ли 2027 год високосным
>>> calendar.isleap(2027)
False

# 6. С помощью модуля calendar узнайте, каким днем недели был день 25 июня 1995 года
>>> calendar.weekday(1995, 6, 25)
6

# 7. Выведите в консоль календарь на 2023 год
>>> print(calendar.calendar(2023))
                                  2023

      January                           February                           March
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
                               1                  1   2   3   4   5                      1  2  3  4  5
 2   3   4   5   6   7   8        6   7   8   9 10 11 12         6   7   8   9 10 11 12
 9 10 11 12 13 14 15       13 14 15 16 17 18 19      13 14 15 16 17 18 19
16 17 18 19 20 21 22      20 21 22 23 24 25 26      20 21 22 23 24 25 26
23 24 25 26 27 28 29      27 28                               27 28 29 30 31
30 31

       April                               May                                    June
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
                           1   2             1  2  3  4  5  6  7                          1  2  3  4
  3   4   5   6   7   8   9        8   9 10 11 12 13 14        5   6   7   8   9 10 11
10 11 12 13 14 15 16      15 16 17 18 19 20 21      12 13 14 15 16 17 18
17 18 19 20 21 22 23      22 23 24 25 26 27 28      19 20 21 22 23 24 25
24 25 26 27 28 29 30      29 30 31                          26 27 28 29 30

        July                                August                             September
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
                            1  2             1   2   3   4   5   6                           1   2   3
  3   4   5   6   7   8   9        7   8   9 10 11 12 13        4   5   6   7   8   9 10
10 11 12 13 14 15 16      14 15 16 17 18 19 20      11 12 13 14 15 16 17
17 18 19 20 21 22 23      21 22 23 24 25 26 27      18 19 20 21 22 23 24
24 25 26 27 28 29 30      28 29 30 31                     25 26 27 28 29 30
31

      October                            November                        December
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
                                1                 1   2   3   4   5                            1   2   3
  2   3   4   5   6   7   8       6   7   8   9  10 11 12       4   5   6   7   8   9  10
 9 10 11 12 13 14 15      13 14 15 16 17 18 19      11 12 13 14 15 16 17
16 17 18 19 20 21 22      20 21 22 23 24 25 26     18 19 20 21 22 23 24
23 24 25 26 27 28 29      27 28 29 30                     25 26 27 28 29 30 31
30 31

Задание 4.5

Условие
Задание 2
Репозиторий PyPI. Пакет FuzzyWuzzy.

Пакет FuzzyWuzzy - это библиотека для нечеткого сравнения строк. Нечеткое сравнение строк позволяет не просто сказать - одинаковые строки или нет, а определить степень их похожести. В текущем задании предлагаем вам поработать с данной библиотекой: 

1. Изучите документацию для пакета fuzzywuzzy на https://pypi.org/
2. Установите его с помощью менеджера пакетов pip
3. Определите, какие модули включает пакет fuzzywuzzy
4. Изучите модуль для базового сравнения строк fuzz(входит в пакет), получите список доступных атрибутов.
5. Изучите синтаксис метода для базового нечеткого сравнения строк ratio() (входит в состав модуля fuzz). 
Прим.: Данный метод возвращает индекс схожести 2 срок
6. Воспользуйтесь методом ratio() для сравнения следующих срок:
   1) 'Плохой код на самом деле не плохой.' и 'Его просто не так поняли.' 
   2) 'Работает? Не трогай.' и 'Работает? Не трогай.' 
   3) 'Работает? Не трогай.' и 'Работает? Не трогай!
Решение - Терминал
# 2. Установите пакет fuzzywuzzy с помощью менеджера пакетов pip
$ pip3 install fuzzywuzzy
Collecting fuzzywuzzy
  Downloading fuzzywuzzy-0.18.0-py2.py3-none-any.whl (18 kB)
Installing collected packages: fuzzywuzzy
Successfully installed fuzzywuzzy-0.18.0
Решение - Интерактивный режим
# 3. Определите, какие модули включает пакет fuzzywuzzy
>>> help('fuzzywuzzy')
Help on package fuzzywuzzy:

NAME
    fuzzywuzzy - # -*- coding: utf-8 -*-

PACKAGE CONTENTS
    StringMatcher
    fuzz
    process
    string_processing
    utils

VERSION
    0.18.0

FILE
    /usr/local/lib/python3.7/site-packages/fuzzywuzzy/__init__.py


# 4. Изучите модуль для базового сравнения строк fuzz(входит в пакет): импортируйте его и получите список доступных атрибутов.
>>> from fuzzywuzzy import fuzz
>>> dir(fuzz)
['QRatio', 'SequenceMatcher', 'UQRatio', 'UWRatio', 'WRatio', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__warningregistry__', '_process_and_sort', '_token_set', '_token_sort', 'partial_ratio', 'partial_token_set_ratio', 'partial_token_sort_ratio', 'platform', 'ratio', 'token_set_ratio', 'token_sort_ratio', 'unicode_literals', 'utils', 'warnings']


# 5. Изучите синтаксис метода для базового нечеткого сравнения строк ratio()
>>> help(fuzz.ratio)
Help on function ratio in module fuzzywuzzy.fuzz:
ratio(s1, s2)

# 6. Воспользуйтесь методом ratio() для сравнения срок
>>> fuzz.ratio('Плохой код на самом деле не плохой.', 'Его просто не так поняли.') 
33
>>> fuzz.ratio('Работает? Не трогай.', 'Работает? Не трогай.')
100
>>> fuzz.ratio('Работает? Не трогай.', 'Работает? Не трогай!')
95

Задачи по теме


Импорт библиотек в Python. Различие модулей и пакетов, причины их использования. Актуальные вопросы для проверки понимания темы и задание для самостоятельной практики.

6. ООП. Классы и объекты.

В данном уроке говорим про основные принципы объектно-ориентированного программирования: абстракцию, инкапсуляцию, наследование и полиморфизм. Учимся создавать классы и объекты классов в Python. Рассматриваем, чем отличаются понятия поля, свойства, методы и атрибуты класса. Изучаем особенности организации уровней доступа к атрибутам: Public, Protected и Private.

С теоретической частью можно познакомиться в Уроке 6 "Программирование на Python: Принципы ООП. Классы, объекты, поля и методы. Уровни доступа.".

Задание 6.1. Алфавит

Описание классовой структуры
Есть Алфавит, характеристиками которого являются: 
1. Язык
2. Список букв

Для Алфавита можно: 
1. Напечатать все буквы алфавита
2. Посчитать количество букв

Так же есть Английский алфавит, который обладает следующими свойствами: 
1. Язык
2. Список букв
3. Количество букв

Для Английского алфавита можно: 
1. Посчитать количество букв
2. Определить, относится ли буква к английскому алфавиту
3. Получить пример текста на английском языке
Задание
Класс Alphabet
1. Создайте класс Alphabet
2. Создайте метод __init__(), внутри которого будут определены два динамических свойства: 1) lang - язык и 2) letters - список букв. Начальные значения свойств берутся из входных параметров метода.
3. Создайте метод print(), который выведет в консоль буквы алфавита
4. Создайте метод letters_num(), который вернет количество букв в алфавите

Класс EngAlphabet
1. Создайте класс EngAlphabet путем наследования от класса Alphabet
2. Создайте метод __init__(), внутри которого будет вызываться родительский метод __init__(). В качестве параметров ему будут передаваться обозначение языка(например, 'En') и строка, состоящая из всех букв алфавита(можно воспользоваться свойством ascii_uppercase из модуля string).
3. Добавьте приватное статическое свойство __letters_num, которое будет хранить количество букв в алфавите.
4. Создайте метод is_en_letter(), который будет принимать букву в качестве параметра и определять, относится ли эта буква к английскому алфавиту.
5. Переопределите метод letters_num() - пусть в текущем классе классе он будет возвращать значение свойства __letters_num.
6. Создайте статический метод example(), который будет возвращать пример текста на английском языке.

Тесты:
1. Создайте объект класса EngAlphabet
2. Напечатайте буквы алфавита для этого объекта
3. Выведите количество букв в алфавите
4. Проверьте, относится ли буква F к английскому алфавиту
5. Проверьте, относится ли буква Щ к английскому алфавиту
6. Выведите пример текста на английском языке
Решение - IDE
import string

# Алфавит
class Alphabet:

    def __init__(self, language, letters_str):
        self.lang = language
        self.letters = list(letters_str)

    # Печатаем все буквы алфавита
    def print(self):
        print(self.letters)

    # Возвращаем количество букв в алфавите
    def letters_num(self):
        len(self.letters)


# Английский алфавит
class EngAlphabet(Alphabet):

    __letters_num = 26

    def __init__(self):
        super().__init__('En', string.ascii_uppercase)

    # Проверяем, относится ли буква к английскому алфавиту
    def is_en_letter(self, letter):
        if letter.upper() in self.letters:
            return True
        return False

    # Возвращаем количество букв в алфавите
    def letters_num(self):
        return EngAlphabet.__letters_num

    # Печатаем пример текста на английском языке
    @staticmethod
    def example():
        print("English Example:\nDon't judge a book by it's cover.")


# Тесты
if __name__ == '__main__':
    eng_alphabet = EngAlphabet()
    eng_alphabet.print()
    print(eng_alphabet.letters_num())
    print(eng_alphabet.is_en_letter('F'))
    print(eng_alphabet.is_en_letter('Щ'))
    EngAlphabet.example()
Вывод в консоль
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
26
True
False
English Example:
Don't judge a book by it's cover.

Задание 6.2. Садовник и помидоры

Описание классовой структуры
Есть Помидор со следующими характеристиками: 
1. Индекс
2. Стадия зрелости(стадии: Отсутствует, Цветение, Зеленый, Красный)

Помидор может: 
1. Расти (переходить на следующую стадию созревания)
2. Предоставлять информацию о своей зрелости

Есть Куст с помидорами, который: 
1. Содержит список томатов, которые на ней растут

И может: 
1. Расти вместе с томатами
2. Предоставлять информацию о зрелости всех томатов
3. Предоставлять урожай

И также есть Садовник, который имеет: 
1. Имя
2. Растение, за которым он ухаживает

И может: 
1. Ухаживать за растением
2. Собирать с него урожай
Задание
Класс Tomato:
1. Создайте класс Tomato
2. Создайте статическое свойство states, которое будет содержать все стадии созревания помидора
3. Создайте метод __init__(), внутри которого будут определены два динамических protected свойства: 1) _index - передается параметром и 2) _state - принимает первое значение из словаря states
4. Создайте метод grow(), который будет переводить томат на следующую стадию созревания
5. Создайте метод is_ripe(), который будет проверять, что томат созрел (достиг последней стадии созревания)

Класс TomatoBush
1. Создайте класс TomatoBush
2. Определите метод __init__(), который будет принимать в качестве параметра количество томатов и на его основе будет создавать список объектов класса Tomato. Данный список будет храниться внутри динамического свойства tomatoes.
3. Создайте метод grow_all(), который будет переводить все объекты из списка томатов на следующий этап созревания
4. Создайте метод all_are_ripe(), который будет возвращать True, если все томаты из списка стали спелыми
5. Создайте метод give_away_all(), который будет чистить список томатов после сбора урожая

Класс Gardener
1. Создайте класс Gardener
2. Создайте метод __init__(), внутри которого будут определены два динамических свойства: 1) name - передается параметром, является публичным и 2) _plant - принимает объект класса Tomato, является protected
3. Создайте метод work(), который заставляет садовника работать, что позволяет растению становиться более зрелым
4. Создайте метод harvest(), который проверяет, все ли плоды созрели. Если все - садовник собирает урожай. Если нет - метод печатает предупреждение.
5. Создайте статический метод knowledge_base(), который выведет в консоль справку по садоводству.

Тесты:
1. Вызовите справку по садоводству
2. Создайте объекты классов TomatoBush и Gardener
3. Используя объект класса Gardener, поухаживайте за кустом с помидорами
4. Попробуйте собрать урожай
5. Если томаты еще не дозрели, продолжайте ухаживать за ними
6. Соберите урожай
Решение - IDE
class Tomato:

    # Стадии созревания помидора
    states = {0: 'nothing', 1: 'flower', 2: 'green_tomato', 3: 'red_tomato'}

    def __init__(self, index):
        self._index = index
        self._state = 0

    # Переход к следующей стадии созревания
    def grow(self):
        self._change_state()

    # Проверка, созрел ли томат
    def is_ripe(self):
        if self._state == 3:
            return True
        return False

    # Защищенные(protected) методы

    def _change_state(self):
        if self._state < 3:
            self._state += 1
        self._print_state()

    def _print_state(self):
        print(f'Tomato {self._index} is {Tomato.states[self._state]}')


class TomatoBush:

    # Создаем список из объектов класса Tomato
    def __init__(self, num):
        self.tomatoes = [Tomato(index) for index in range(0, num)]

    # Переводим все томаты из списка на следующий этап созревания
    def grow_all(self):
        for tomato in self.tomatoes:
            tomato.grow()

    # Проверяем, все ли помидоры созрели
    def all_are_ripe(self):
        return all([tomato.is_ripe() for tomato in self.tomatoes])

    # Собираем урожай
    def give_away_all(self):
        self.tomatoes = []


class Gardener:

    # Выдаем садовнику растение для ухода
    def __init__(self, name, plant):
        self.name = name
        self._plant = plant

    # Ухаживаем за растением
    def work(self):
        print('Gardener is working...')
        self._plant.grow_all()
        print('Gardener finished')

    # Собираем урожай
    def harvest(self):
        print('Gardener is harvesting...')
        if self._plant.all_are_ripe():
            self._plant.give_away_all()
            print('Harvesting is finished')
        else:
            print('Too early! Your plant is green and not ripe.')

    # Статический метод
    # Выводит справку по садоводству
    @staticmethod
    def knowledge_base():
        print('''Harvest time for tomatoes should ideally occur
when the fruit is a mature green and
then allowed to ripen off the vine.
This prevents splitting or bruising
and allows for a measure of control over the ripening process.''')


# Тесты
if __name__ == '__main__':
    Gardener.knowledge_base()
    great_tomato_bush = TomatoBush(4)
    gardener = Gardener('Emilio', great_tomato_bush)
    gardener.work()
    gardener.work()
    gardener.harvest()
    gardener.work()
    gardener.harvest()
Вывод в консоль
Harvest time for tomatoes should ideally occur
when the fruit is a mature green and
then allowed to ripen off the vine.
This prevents splitting or bruising
and allows for a measure of control over the ripening process.
Gardener is working...
Tomato 0 is flower
Tomato 1 is flower
Tomato 2 is flower
Gardener finished
Gardener is working...
Tomato 0 is green_tomato
Tomato 1 is green_tomato
Tomato 2 is green_tomato
Gardener finished
Gardener is harvesting...
Too early! Your plant is green and not ripe.
Gardener is working...
Tomato 0 is red_tomato
Tomato 1 is red_tomato
Tomato 2 is red_tomato
Gardener finished
Gardener is harvesting...
Harvesting is finished

Задание 6.3. Покупка дома

Описание классовой структуры
Есть Человек, характеристиками которого являются:
1. Имя
2. Возраст
3. Наличие денег
4. Наличие собственного жилья

Человек может:
1. Предоставить информацию о себе 
2. Заработать деньги
3. Купить дом

Также же есть Дом, к свойствам которого относятся:
1. Площадь
2. Стоимость

Для Дома можно:
1. Применить скидку на покупку

Также есть Небольшой Типовой Дом, обязательной площадью 40м2.
Задание
Класс Human

1. Создайте класс Human. 
2. Определите для него два статических поля: default_name и default_age.
3. Создайте метод __init__(), который помимо self принимает еще два параметра: name и age. Для этих параметров задайте значения по умолчанию, используя свойства default_name и default_age. В методе __init__() определите четыре свойства: Публичные - name и age. Приватные - money и house.
4. Реализуйте справочный метод info(), который будет выводить поля name, age, house и money.
5. Реализуйте справочный статический метод default_info(), который будет выводить статические поля default_name и default_age.
6. Реализуйте приватный метод make_deal(), который будет отвечать за техническую реализацию покупки дома: уменьшать количество денег на счету и присваивать ссылку на только что купленный дом. В качестве аргументов данный метод принимает объект дома и его цену.
7. Реализуйте метод earn_money(), увеличивающий значение свойства money.
8. Реализуйте метод buy_house(), который будет проверять, что у человека достаточно денег для покупки, и совершать сделку. Если денег слишком мало - нужно вывести предупреждение в консоль. Параметры метода: ссылка на дом и размер скидки


Класс House

1. Создайте класс House
2. Создайте метод __init__() и определите внутри него два динамических свойства: _area и _price. 3. Свои начальные значения они получают из параметров метода __init__() 
4. Создайте метод final_price(), который принимает в качестве параметра размер скидки и возвращает цену с учетом данной скидки.


Класс SmallHouse

1. Создайте класс SmallHouse, унаследовав его функционал от класса House
2. Внутри класса SmallHouse переопределите метод __init__() так, чтобы он создавал объект с площадью 40м2


Тесты

1. Вызовите справочный метод  default_info() для класса Human()
2. Создайте объект класса Human
3. Выведите справочную информацию о созданном объекте (вызовите метод info()).
4. Создайте объект класса SmallHouse
5. Попробуйте купить созданный дом, убедитесь в получении предупреждения.
6. Поправьте финансовое положение объекта - вызовите метод earn_money()
7. Снова попробуйте купить дом
8. Посмотрите, как изменилось состояние объекта класса Human



Решение - IDE
class Human:

    # Статические поля
    default_name = 'No name'
    default_age = 0

    def __init__(self, name=default_name, age=default_age):
        # Динамические поля
        # Публичные
        self.name = name
        self.age = age
        # Приватные
        self.__money = 0
        self.__house = None

    def info(self):
        print(f'Name: {self.name}')
        print(f'Age: {self.age}')
        print(f'Money: {self.__money}')
        print(f'House: {self.__house}')

    # Статический метод
    @staticmethod
    def default_info():
        print(f'Default Name: {Human.default_name}')
        print(f'Default Age: {Human.default_age}')

    def earn_money(self, amount):
        self.__money += amount
        print(f'Earned {amount} money! Current value: {self.__money}')

    def buy_house(self, house, discount):
        price = house.final_price(discount)
        if self.__money >= price:
            self.__make_deal(house, price)
        else:
            print('Not enough money!')

    # Приватный метод
    def __make_deal(self, house, price):
        self.__money -= price
        self.__house = house


class House:

    def __init__(self, area, price):
        self._area = area
        self._price = price

    def final_price(self, discount):
        final_price = self._price * (100 - discount) / 100
        print(f'Final price: {final_price}')
        return final_price


class SmallHouse(House):

    default_area = 40

    def __init__(self, price):
        super().__init__(SmallHouse.default_area, price)


if __name__ == '__main__':

    Human.default_info()

    alexander = Human('Sasha', 27)
    alexander.info()

    small_house = SmallHouse(8_500)

    alexander.buy_house(small_house, 5)

    alexander.earn_money(5_000)
    alexander.buy_house(small_house, 5)

    alexander.earn_money(20_000)
    alexander.buy_house(small_house, 5)
    alexander.info()
Вывод в консоль
Default Name: No name
Default Age: 0
Name: Sasha
Age: 27
Money: 0
House: None
Final price: 8075.0
Not enough money!
Earned 5000 money! Current value: 5000
Final price: 8075.0
Not enough money!
Earned 20000 money! Current value: 25000
Final price: 8075.0
Name: Sasha
Age: 27
Money: 16925.0
House: <__main__.SmallHouse object at 0x10c460890>
Как вам материал?

Также может быть интересно