#!/usr/bin/env python # coding: utf-8 # # Основы программирования в Python # # ## Домашнее задание №2 # # *Формат задания и некоторые задачи заимствованы из [домашнего задания](http://nbviewer.jupyter.org/url/python.math-hse.info/static/assignments_release/dj2017/ps01/ps01.ipynb) по [курсу](http://math-info.hse.ru/s17/1) «Введение в программирование» (Магистерская программа «Журналистика данных», НИУ ВШЭ, 2017-18). * # # За разные задачи можно получить разное число баллов. Если не указано обратное, задача весит 1 балл. Максимум за ДЗ можно набрать 6 баллов (это соответствует оценке 10), но вы можете решить больше задач, чем требуется, чтобы потренироваться. # # Для предварительной проверки задания нужно сделать следующее: # # 1. Скачать данный `ipynb`-файл на свой компьютер, открыть его в Jupyter Notebook. # 2. Активировать тесты (см. ниже). # 3. Вставить решение каждой задачи в ячейку для кода, следующую за его условием, там, где написан комментарий `# YOUR CODE HERE`. Отступ вашего кода должен составлять 4 пробела. Ничего не менять вокруг! # 4. Запустить ячейку, в которую вы вставили код с решением. Ввести какие-то входные данные, проверить визуально правильность вывода. # 5. Запустить следующую ячейку (в ней содержится тест). Если запуск ячейки с тестом не приводит к появлению ошибки (assertion), значит, всё в порядке, задача решена. Если приводит к появлению ошибки, значит, тест не пройден и нужно искать ошибку. # # **Внимание!** Если в какой-то момент забыть ввести входные данные и перейти на следующую ячейку, есть риск, что Notebook перестанет откликаться. В этом случае надо перезапустить ядро: *Kernel → Restart*. При этом потеряются все значения переменных, но сам код останется. # # Чтобы сдать ДЗ, его надо загрузить по ссылке на Dropbox в виде `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 # ### Задача 0 (не оценивается, решена для примера) # # Напишите программу, которая запрашивает у пользователя целое число и выводит на экран сообщение вида: # # Следующее число: [число]. # # **Пример** # # *Входные данные* # # Введите целое число: 7 # # *Выходные данные* # # Следующее число 8. # In[ ]: def nnext(): n = int(input("Введите целое число: ")) res = n + 1 print(f"Следующее число: {res}.") nnext() # In[ ]: test_data = [("-1", "Следующее число: 0."), ("-20", "Следующее число: -19."), ("5", "Следующее число: 6."), ("11", "Следующее число: 12."), ("460", "Следующее число: 461.") ] for inp, out in test_data: with Tester(inp.split()) as t: nnext() assert len(t) == 1, "Вам нужно вывести ровно одну строку с ответом" assert t[0].strip() == out, "Неверный ответ, были введены числа " + inp # ### Задача 1 # Напишите программу, которая запрашивает у пользователя размер обуви и выводит на экран размер подходящих скальных туфель (туфли для скалолазания), учитывая, что обычно размер скальных туфель на 2 размера меньше обычного. # # **Пример** # # *Входные данные* # # Введите размер обуви: 38 # # *Выходные данные* # # 36 # In[ ]: def shoes(): # YOUR CODE HERE shoes() # In[ ]: test_data = [("38", 36), ("41", 39), ("35", 33), ("39", 37), ("46", 44) ] for inp, out in test_data: with Tester(inp.split()) as t: shoes() assert len(t) == 1, "Вам нужно вывести ровно одну строку с ответом" assert t[0].strip() == str(out), "Неверный ответ, были введены числа " + inp # ### Задача 2 # Напишите программу, которая последовательно запрашивает с клавиатуры три целых числа (после ввода каждого числа пользователь нажимает *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 # ### Задача 3 # # Напишите программу, которая запрашивает у пользователя его имя и выводит на экран сообщение в одну строчку (пробелы важны): # # Имя... какое хорошее имя! # # **Примеры:** # # *Входные данные:* # # Анна # # *Выходные данные:* # # Анна... какое хорошее имя! # # *Входные данные:* # # Николай # # *Выходные данные:* # # Николай... какое хорошее имя! # 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 # ### Задача 4 # # Напишите программу, которая последовательно запрашивает с клавиатуры два положительных числа (целых или с плавающей точкой) и выводит на экран их [среднее геометрическое](https://ru.wikipedia.org/wiki/%D0%A1%D1%80%D0%B5%D0%B4%D0%BD%D0%B5%D0%B5_%D0%B3%D0%B5%D0%BE%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5). Считайте, что пользователь вводит только неотрицательные числа. После ввода каждого числа пользователь нажимает *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 # ### Задача 5 # # В среднем за неделю Питон получает пять сообщений от Анаконды ($\lambda = 5$). Пользователь с клавиатуры вводит число сообщений, которые Анаконда может прислать Питону (число $k$). Напишите программу, которая выводит на экран вероятность, с которой Питон получит $k$ сообщений от Анаконды за неделю, с точностью до *трёх* знаков после запятой. Сообщение, выводимое на экран, должно быть таким (вместо выражений в квадратных скобках подставляются значения): # # Число сообщений от Анаконды за неделю равно [k], вероятность равна [значение]. # # Вероятность того, что Питон получит ровно $k$ сообщений, определяется следующим образом (распределение Пуассона): # # $$P(X = k) = e^{-\lambda}\cdot \frac{\lambda^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 # ### Задача 6 # # Напишите программу, которая запрашивает у пользователя сумму (в рублях), которую он хочет перевести своему другу на карту другого банка, и возвращает сумму списания (в рублях) с учётом комиссии банка 5%. # # *Примечание:* считайте, что сумма перевода – целое число. # # **Пример:** # # *Входные данные* # # Введите сумму для перевода: 1000 # # *Выходные данные* # # Сумма списания: 1050.0 # In[ ]: def bank(): # YOUR CODE HERE bank() # In[ ]: test_data = [ ("0", ["Сумма списания: 0.0\n"]), ("100", ["Сумма списания: 105.0\n"]), ("257", ["Сумма списания: 269.85\n"]), ("5450", ["Сумма списания: 5722.5\n"]), ("13200", ["Сумма списания: 13860.0\n"]) ] for inp, out in test_data: with Tester([inp]) as t: bank() assert len(t) == 1, "Вам нужно вывести ровно одну строку с ответом" assert t == out,"Неверный ответ, было введено число " + inp # ### Задача 7 (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) # ### Задача 8 (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)