Программирование для всех

Домашнее задание №1

Разработчик формата сдачи заданий и фабрики автоматических тестов: Щуров И.В.
Автор задач: Тамбовцева А.А.

За разные задачи можно получить разное число баллов. Чтобы получить оценку 10, достаточно набрать 6 баллов. Вы можете решить больше задач, чем требуется, чтобы потренироваться.

Формат сдачи

Для предварительной проверки задания нужно сделать следующее:

  1. Скачать данный ipynb-файл на свой компьютер, открыть его в Jupyter Notebook.
  2. Активировать тесты (см. ниже).
  3. Вставить решение каждой задачи в ячейку для кода, следующую за его условием, там, где написан комментарий # YOUR CODE HERE. Отступ вашего кода должен составлять 4 пробела. Ничего не менять вокруг!
  4. Запустить ячейку, в которую вы вставили код с решением. Ввести какие-то входные данные, проверить визуально правильность вывода.
  5. Запустить следующую ячейку (в ней содержится тест). Если запуск ячейки с тестом не приводит к появлению ошибки (assertion), значит, всё в порядке, задача решена. Если приводит к появлению ошибки, значит, тест не пройден и нужно искать ошибку.

Внимание! Если в какой-то момент забыть ввести входные данные и перейти на следующую ячейку, есть риск, что Notebook перестанет откликаться. В этом случае надо перезапустить ядро: Kernel → Restart. При этом потеряются все значения переменных, но сам код останется.

Чтобы сдать ДЗ, его надо загрузить в nbgr-x в виде ipynb-файла. Получить ipynb-файл можно, выбрав в Jupyter пункт меню File → Download as... → Notebook (.ipynb).

Активировать тесты

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

In [ ]:
# Фабрика тестов для проверки программ, принимающих данные через input()

from collections import deque

class Tester(object):
    def __init__(self, inp):
        self.outputs = []
        self.inputs = deque(inp)
    def print(self, *args, sep = " ", end = "\n"):
        text = sep.join(map(str, args)) + end
        newlines = text.splitlines(keepends=True)
        if self.outputs and self.outputs[-1] and self.outputs[-1][-1] != "\n" and newlines:
            self.outputs[-1] += newlines[0]
            self.outputs.extend(newlines[1:])
        else:
            self.outputs.extend(newlines)
            
    def input(self, *args):
        assert self.inputs, "Вы пытаетесь считать больше элементов, чем предусмотрено условием"
        return self.inputs.popleft()
    def __enter__(self):
        global print
        global input
        print = self.print
        input = self.input
        return self.outputs
    def __exit__(self, *args):
        global print
        global input
        del print
        del input

Задача 1. Лучше гор могут быть только горы... (1 балл)

Напишите программу, которая запрашивает у пользователя размер обуви (целое число) и выводит на экран размер туфель для скалолазания, учитывая, что обычно размер скальных туфель на два размера меньше обычного.

Пример работы программы

Ввод:

38

Вывод:

36
In [ ]:
def problem01():
    
    "# YOUR CODE HERE"

problem01()
In [ ]:
test_data = [
    ("38", "36"),
    ("40", "38"),
    ("42", "40"),
    ("36", "34")
]

for inp, out in test_data:
    with Tester([inp]) as t:
        problem01()
        assert len(t) == 1, "Вам нужно вывести ровно одну строку с ответом"
        assert t[0] == out+"\n", "Неверный ответ, была введена строка " + inp

Задача 2. В синем море, в белой пене... (1 балл)

В Светлогорске, в музее Мирового океана есть прекрасные весы, которые позволяют узнать свой вес, измеренный в селёдках, в китах, в креветках и в других морских обитателях.

Напишите программу, которая запрашивает у пользователя с клавиатуры его вес в килограммах (целое или дробное число) и выводит на экран его вес в селёдках, округлённый до целого числа. Считайте, что средний вес селёдки равен 350 граммам.

Пример работы программы

Ввод:

56

Вывод:

Ваш вес в селёдках: 160.
In [ ]:
def problem02():
    
    "# YOUR CODE HERE"

problem02()
In [ ]:
test_data = [
    ("56", "Ваш вес в селёдках: 160."),
    ("35", "Ваш вес в селёдках: 100."),
    ("64", "Ваш вес в селёдках: 182."),
    ("82", "Ваш вес в селёдках: 234."),
    ("40.5", "Ваш вес в селёдках: 115."),
    ("47.25", "Ваш вес в селёдках: 135.")
]

for inp, out in test_data:
    with Tester([inp]) as t:
        problem02()
        assert len(t) == 1, "Вам нужно вывести ровно одну строку с ответом"
        assert t[0] == out+"\n", "Неверный ответ, была введена строка " + inp

Задача 3. Точность – вежливость королей (1 балл)

В машинном обучении существуют специальные меры, которые позволяют определить качество модели. Среди них — точность (precision), полнота (recall) и F-мера. F-мера вычисляется так:

$$ F = 2 \times \frac{\text{precision}\times \text{recall}}{\text{precision}+\text{recall}} $$

Напишите программу, которая запрашивает с клавиатуры значение precision, затем значение recall (отдельный запрос для каждого значения), вычисляет F-меру и выводит её на экран с точностью до третьего знака после запятой.

Пример работы программы

Ввод:

0.9
0.85

Вывод:

F: 0.874
In [ ]:
def problem03():
    
    "# YOUR CODE HERE"

problem03()
In [ ]:
test_data = [
    ("0.9 0.85", "F: 0.874"),
    ("0.65 0.68", "F: 0.665"),
    ("0.727 0.563", "F: 0.635"), 
    ("0.41 0.5", "F: 0.451"),
    ("0 1", "F: 0.000"),
    ("1 0", "F: 0.000")
]

for inp, out in test_data:
    with Tester(inp.split()) as t:
        problem03()
        assert len(t) == 1, "Вам нужно вывести ровно одну строку с ответом"
        assert t[0] == out+"\n", "Неверный ответ, была введена строка " + inp

Задача 4. Power of numbers (1 балл)

Напишите программу, которая запрашивает с клавиатуры два целых положительных числа a и b (отдельный запрос для каждого значения) и выводит на экран строку следующего вида, с подставленными значениями на месте квадратных скобок:

[a] в степени [b] равно [значение 1], [b] в степени [a] равно [значение 2]

Примеры работы программы

Ввод:

2
3

Вывод:

2 в степени 3 равно 8, 3 в степени 2 равно 9

Ввод:

4
3

Вывод:

4 в степени 3 равно 64, 3 в степени 4 равно 81
In [ ]:
def problem04():
    
    "# YOUR CODE HERE"

problem04()
In [ ]:
test_data = [
    ("4 3", "4 в степени 3 равно 64, 3 в степени 4 равно 81"),
    ("2 5", "2 в степени 5 равно 32, 5 в степени 2 равно 25"),
    ("3 6", "3 в степени 6 равно 729, 6 в степени 3 равно 216"), 
    ("1 5", "1 в степени 5 равно 1, 5 в степени 1 равно 5"),
    ("1 1", "1 в степени 1 равно 1, 1 в степени 1 равно 1")
]

for inp, out in test_data:
    with Tester(inp.split()) as t:
        problem04()
        assert len(t) == 1, "Вам нужно вывести ровно одну строку с ответом"
        assert t[0] == out+"\n", "Неверный ответ, была введена строка " + inp

Задача 5. Ты не сорвёшь цветка, чтоб не поблёк он... (2 балла)

Согласно либретто оперы Ш.Гуно «Фауст», Мефистофель предсказал Зибелю, что он не сможет сорвать цветка, чтобы тот не завял. Итак, Зибель загадал следующее:

  • Если он сорвёт две ромашки и в сумме число лепестков будет нечётным, он сможет собрать букет, который не завянет, и преподнести его Маргарите.

  • Если он сорвёт две ромашки и в сумме число лепестков будет чётным, он попробует сорвать ещё третью. Если и тогда сумма будет чётной, он повременит с букетом и просто пойдёт грустить и думать дальше. А если сумма лепестков трёх ромашек всё же окажется нечётной, он попробует собрать букет.

Напишите программу, которая запрашивает с клавиатуры число лепестков на первой и второй ромашке (отдельный запрос для каждого значения) и выводит на экран количество ромашек, которое необходимо ещё сорвать для принятия окончательного решения.

При решении этой задачи нельзя использовать конструкцию if-else (даже если вы с ней знакомы) и любые способы явной проверки выполнения условий, например, с помощью оператора ==.

Пример работы программы

Ввод:

16
17


Вывод:

0

Ввод:

14
12


Вывод:

1


Ввод:

11
19


Вывод:

1    
In [ ]:
def problem05():
    
    "# YOUR CODE HERE"

problem05()
In [ ]:
test_data = [
    ("13 10", "0"),
    ("11 19", "1"),
    ("16 17", "0"), 
    ("15 20", "0"),
    ("14 18", "1")
]

for inp, out in test_data:
    with Tester(inp.split()) as t:
        problem05()
        assert len(t) == 1, "Вам нужно вывести ровно одну строку с ответом"
        assert t[0] == out+"\n", "Неверный ответ, была введена строка " + inp

Задача 6. Разделяй и властвуй (2 балла)

Напишите программу, которая запрашивает с клавиатуры целое положительное четырёхзначное число, сохраняет его в числовом формате (тип integer) и выводит на экран его представление в следующем виде (с подставленными значениями на месте квадратных скобок):

[тысячи] * 1000 + [сотни] * 100 + [десятки] * 10 + [единицы]

Важно: «сохраняет в числовом виде» – обязательное условие, нельзя просто извлечь первый/второй/третий/четвёртый символ строки и подставить в текстовый шаблон, нужно работать с числом! Иначе это была бы простая задача :)

Примеры работы программы

Ввод:

1234

Вывод:

1 * 1000 + 2 * 100 + 3 * 10 + 4

Ввод:

9000

Вывод:

9 * 1000 + 0 * 100 + 0 * 10 + 0
In [ ]:
def problem06():
    
    "# YOUR CODE HERE"

problem06()
In [ ]:
test_data = [
    ("1234", "1 * 1000 + 2 * 100 + 3 * 10 + 4"),
    ("1046", "1 * 1000 + 0 * 100 + 4 * 10 + 6"),
    ("3600", "3 * 1000 + 6 * 100 + 0 * 10 + 0"), 
    ("9701", "9 * 1000 + 7 * 100 + 0 * 10 + 1"),
    ("1000", "1 * 1000 + 0 * 100 + 0 * 10 + 0"),
    ("9001", "9 * 1000 + 0 * 100 + 0 * 10 + 1"),
    ("4280", "4 * 1000 + 2 * 100 + 8 * 10 + 0")
]

for inp, out in test_data:
    with Tester([inp]) as t:
        problem06()
        assert len(t) == 1, "Вам нужно вывести ровно одну строку с ответом"
        assert t[0] == out+"\n", "Неверный ответ, была введена строка " + inp

Задача 7. Что скрывают звёзды (3 балла)

Напишите программу, которая угадывает, какая цифра была скрыта за «звёздочкой», если известно, что пользователь вводит с клавиатуры сначала одно двузначное число со «звёздочкой» на конце, затем – второе двузначное число со «звёздочкой» в начале, а затем их сумму. Считайте, что сумма чисел тоже является двузначным числом.

При решении этой задачи нельзя использовать конструкцию if-else (даже если вы с ней знакомы) и любые способы явной проверки выполнения условий, например, с помощью операторов > или <.

Подсказка. Извлечь первый элемент строки можно по индексу 0, а второй – по индексу 1, например, так:

s = "abc"
one = s[0]
two = s[1]
print(one)
print(two)

a
b

Примеры работы программы

Ввод:

2*
*1
54

Вывод:

* = 3

Ввод:

1*
*3
90

Вывод:

* = 7
In [ ]:
def problem07():
    
    "# YOUR CODE HERE"

problem07()
In [ ]:
test_data = [
    ("2* *1 54", "* = 3"),
    ("1* *3 90", "* = 7"),
    ("2* *1 65", "* = 4"),
    ("3* *3 44", "* = 1"),
    ("1* *4 80", "* = 6"),
    ("1* *6 71", "* = 5")
]

for inp, out in test_data:
    with Tester(inp.split()) as t:
        problem07()
        assert len(t) == 1, "Вам нужно вывести ровно одну строку с ответом"
        assert t[0] == out+"\n", "Неверный ответ, была введена строка " + inp