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

Формат задания и некоторые задачи заимствованы из домашнего задания по курсу «Введение в программирование» (Магистерская программа «Журналистика данных», НИУ ВШЭ, 2017-18).

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

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

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

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

Чтобы сдать ДЗ, его надо загрузить в nbgr-x в виде ipynb-файла. Получить ipynb-файл можно, выбрав в Jupyter пункт меню File → Download as... → IPython 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

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

Пример.

Входные данные:

1
2
3

Выходные данные:

6
In [ ]:
def prod3():
    # YOUR CODE HERE
prod3()
In [ ]:
test_data = [
    ("0 0 0", 0),
    ("0 3 10", 0),
    ("3 0 10", 0),
    ("2 4 0", 0),
    ("2 4 5", 40),
    ("-1 2 100", -200),
    ("-20 -30 200", 200*20*30),
    ("-5 -180 -12", -5*180*12)
]

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

Задача 2

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

Имя... какое хорошее имя!

Примеры:

Входные данные:

Анна

Выходные данные:

Анна... какое хорошее имя!

Входные данные:

Николай

Выходные данные:

Николай... какое хорошее имя!
In [ ]:
def good_name():
    # YOUR CODE HERE

good_name()
In [ ]:
test_data = [
    ("Алла", "Алла... какое хорошее имя!"),
    ("Петя", "Петя... какое хорошее имя!"),
    ("Мэри", "Мэри... какое хорошее имя!"),
    ("Саша", "Саша... какое хорошее имя!")
]

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

Задача 3

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

Примеры:

Входные данные:

3
12

Выходные данные:

6.0

Входные данные:

5
4    

Выходные данные:

4.47213595499958
In [ ]:
def geom_mean():
    # YOUR CODE HERE
    
geom_mean()
In [ ]:
test_data = [
    ("3 12", 6.),
    ("5 10", 7.0710678118654755),
    ("18 24", 20.784609690826528),
    ("0.1 8.1", 0.9),
    ("0.05 0.12", 0.07745966692414834),
    ("12.25 23.189", 16.8542353727483)
]

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

Задача 4

В среднем за неделю Питон получает пять сообщений от Анаконды. Пользователь с клавиатуры вводит число сообщений, которые Анаконда может прислать Питону (число $k$). Напишите программу, которая выводит на экран вероятность, с которой Питон получит $k$ сообщений от Анаконды за неделю, с точностью до трех знаков после запятой. Сообщение, выводимое на экран, должно быть таким:

Число сообщений от Анаконды за неделю равно k, вероятность равна значение.

Вероятность того, что Питон получит ровно $k$ сообщений, определяется следующим образом (распределение Пуассона):

$$P(X = k) = e^{-5}\cdot \frac{5^k}{k!},$$

где $k!$ – «ка факториал», произведение всех целых чисел от 1 до $k$ включительно.

Подсказка: функцию для вычисления факториала можно вызвать из модуля math (factorial()).

Пример:

Входные данные

Введите число сообщений: 2

Выходные данные

Число сообщений от Анаконды за неделю равно 2, вероятность равна 0.084.
In [ ]:
def pois():
    # YOUR CODE HERE
pois()    
In [ ]:
test_data = [
    ("0", ["Число сообщений от Анаконды за неделю равно 0, вероятность равна 0.007.\n"]),
    ("1", ["Число сообщений от Анаконды за неделю равно 1, вероятность равна 0.034.\n"]),
    ("2", ["Число сообщений от Анаконды за неделю равно 2, вероятность равна 0.084.\n"]),
    ("5", ["Число сообщений от Анаконды за неделю равно 5, вероятность равна 0.175.\n"]),
    ("7", ["Число сообщений от Анаконды за неделю равно 7, вероятность равна 0.104.\n"])
]

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

Задача 5 (2 балла)

Дано целое число $n$. Выведите следующее за ним четное число. При решении этой задачи нельзя использовать условный оператор if и циклы.

Подсказка. Бывает оператор целочисленного деления // и взятия остатка при делении %. Например, результат выполнения операции 15 % 7 равен 1.

Примеры

Входные данные

7

Выходные данные

8

Входные данные

8

Выходные данные

10
In [ ]:
def next_even():
    # YOUR CODE HERE
    
next_even()
In [ ]:
test_data = [
    (1, 2),
    (2, 4),
    (100, 102),
    (0, 2),
    (11, 12),
    (594843, 594844),
    (-1, 0),
    (-100, -98)
]

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

Задача 6 (3 балла)

Электронные часы показывают время в формате h:mm:ss, то есть сначала записывается количество часов (в 24-часовом формате), потом обязательно двузначное количество минут, затем обязательно двузначное количество секунд. Количество минут и секунд при необходимости дополняются до двузначного числа нулями.

С начала суток прошло n секунд. Выведите, что покажут часы.

Запрещается пользоваться условным оператором, циклами и любыми библиотеками.

Входные данные

Вводится целое число $n$.

Выходные данные

Выведите ответ на задачу, соблюдая требуемый формат.

Примеры

Входные данные

3602

Выходные данные

1:00:02

Входные данные

129700

Выходные данные

12:01:40
In [ ]:
def clock():
    # YOUR CODE HERE
    
clock()
In [ ]:
test_data = [
    (3602, "1:00:02"),
    (129700, "12:01:40"),
    (12739182731927, "13:58:47"),
    (0, "0:00:00"),
    (1, "0:00:01"),
    (60, "0:01:00"),
    (3600, "1:00:00"),
    (3599, "0:59:59"),
    (43200, "12:00:00"),
    (86400, "0:00:00")
]

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