Домашнее задание 3

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

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

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

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

Обратите внимание:

  • В этом домашнем задании запрашивать информацию у пользователя с клавиатуры не требуетсяinput() не нужен.
  • Название функции должно совпадать с названием, указанным в задаче, иначе ваше решение не пройдет тест.
  • Решение любой задачи должно начинаться со строчки с def.

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

Запустите следующие ячейку, чтобы иметь возможность запускать тесты. Эту операцию нужно проделывать каждый раз, когда вы перезапускаете ядро. Если какой-то из тестов говорит NameError: name 'Tester' is not defined, нужно запустить эту ячейку ещё раз.

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

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

Примеры работы функции:

Применение:

my_expo(2)

Результат:

7.38905609893065

Применение:

my_expo(-1.5)

Результат:

0.22313016014842982
In [ ]:
# YOUR CODE HERE
In [ ]:
import math
assert(math.isclose(my_expo(1), 2.718281828459045, rel_tol=1e-4, abs_tol=0.0))
assert(math.isclose(my_expo(2),7.38905609893065, rel_tol=1e-4, abs_tol=0.0))
assert(math.isclose(my_expo(-1.5),0.22313016014842982, rel_tol=1e-4, abs_tol=0.0))
assert(math.isclose(my_expo(0), 1.0, rel_tol=1e-4, abs_tol=0.0))
assert(math.isclose(my_expo(3),20.085536923187668, rel_tol=1e-4, abs_tol=0.0))
with Tester([]) as t:
    my_expo(3)
    assert len(t) == 0, "функция ничего не должна печатать"

print("Окей!")

Задача 2

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

Пример работы функции:

Применение:

int_list(['1', '3', '5', '18'])

Результат:

[1, 3, 5, 18]
In [ ]:
# YOUR CODE HERE
In [ ]:
assert(int_list(['1', '3', '5', '18']) == [1, 3, 5, 18])
assert(int_list(['10', '33', '1555', '187']) == [10, 33, 1555, 187])
assert(int_list(['-1', '-3', '-5', '-18']) == [-1, -3, -5, -18])
assert(int_list(['23', '-43', '-5', '21']) == [23, -43, -5, 21])

with Tester([]) as t:
    int_list(['1', '3', '5', '18'])
    assert len(t) == 0, "функция ничего не должна печатать"

print("Окей!")

Задача 3

Напишите функцию ave_mark(d), которая принимает на вход словарь d, ключами которого являются имена студентов, а значениями ‒ их оценки по курсу, и возвращает среднюю оценку по этому курсу без каких-либо округлений. Библиотечные функции mean()использовать нельзя, обычную функцию sum() ‒ можно. Функция не должна ничего печатать (выводить на экран).

Пример работы функции:

Применение:

ave_mark({'Элеонора': 8, 'Адам': 7, 'Урсула': 6, 'Альбер': 10})

Результат:

7.75
In [ ]:
# YOUR CODE HERE
In [ ]:
assert(ave_mark({'Элеонора': 8, 'Адам': 7, 'Урсула': 6, 'Альбер': 10}) == 7.75)
assert(ave_mark({'Климентина': 10, 'Аврора': 5, 'Филипп': 10, 'Джек': 3}) == 7.0)
assert(ave_mark({'Роза' : 5, 'Мерседес': 3, 'Анна': 4, 'Хорхе': 6, 'Фернан': 9, 'Мария': 5}) == 5.333333333333333)
assert(ave_mark({'Алексей': 10, 'Андрей': 8}) == 9.0)
assert(ave_mark({'Ли': 7, 'Ян': 6, 'Ия': 5, 'Эя' : 3, 'Джо' : 10, 'Рю' : 10, 'Эд' : 3, 'Ги' : 7, 'Ая' : 8}) == 6.555555555555555)

with Tester([]) as t:
    ave_mark({'Элеонора': 8, 'Адам': 7, 'Урсула': 6, 'Альбер': 10})
    assert len(t) == 0, "функция ничего не должна печатать"

print("Окей!")

Задача 4

Напишите функцию dummy(f), которая принимает на вход список значений индекса Freedom House f и возвращает список из 0 и 1, где 1 соответствует свободным странам (статус Free, значения индекса от 1.0 до 2.5 включительно). Функция не должна ничего печатать (выводить на экран).

Примеры работы функции:

Применение:

dummy([2.5, 3.0, 2.7, 3.6, 4.8, 6.5, 1.0, 1.5, 7.0])

Результат:

[1, 0, 0, 0, 0, 0, 1, 1, 0]

Применение:

dummy([3.5, 3.0, 2.7, 3.6])

Результат:

[0, 0, 0, 0]
In [ ]:
# YOUR CODE HERE
In [ ]:
assert(dummy([2.5, 3.0, 2.7, 3.6, 4.8, 6.5, 1.0, 1.5, 7.0]) == [1, 0, 0, 0, 0, 0, 1, 1, 0])
assert(dummy([2.4, 1.0, 0.9, 3.5, 2.6]) == [1, 1, 0, 0, 0]) 
assert(dummy([1.8, 0.6, 0.0, 2.8]) == [1, 0, 0, 0])
assert(dummy([3, 4, 5, 6]) == [0, 0, 0, 0])
assert(dummy([1.0, 1.2, 2.3, 1.9, 2.2]) == [1, 1, 1, 1, 1])

with Tester([]) as t:
    dummy([1.8, 0.6, 0.0, 2.8])
    assert len(t) == 0, "функция ничего не должна печатать"

print("Окей!")

Задача 5

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

Подсказка: вспомните про метод .count() для списков и про функцию sorted().

Примеры работы функции:

Применение:

to_give(['Хобби доктора Травена.', 'Хобби доктора Травена.', 'Змеелов.', 'Маленький принц.', 
'Питоны о Питонах. Автобиография', 'Python для детей.', 'Питон для детей.', 'Кролики и удавы.', 
'Маленький принц.', 'Удавы и питоны. Уход и содержание.', 'Питон для детей.'])

Результат:

['Маленький принц.', 'Питон для детей.','Хобби доктора Травена.']

Применение:

to_give(['Змеелов.', 'Маленький принц.','Хобби доктора Травена.'])

Результат:

[]    
In [ ]:
# YOUR CODE HERE
In [ ]:
to_give(['Хобби доктора Травена.', 'Хобби доктора Травена.', 'Змеелов.', 'Маленький принц.', 
'Питоны о Питонах. Автобиография', 'Python для детей.', 'Питон для детей.', 'Кролики и удавы.', 
'Маленький принц.', 'Удавы и питоны. Уход и содержание.', 'Питон для детей.'])
In [ ]:
assert(to_give(['Хобби доктора Травена.', 'Маленький принц.', 'Python для детей.']) == [])
assert(to_give(['Хобби доктора Травена.', 'Хобби доктора Травена.', 'Змеелов.', 'Маленький принц.', 
'Питоны о Питонах. Автобиография', 'Python для детей.', 'Питон для детей.', 'Кролики и удавы.', 
'Маленький принц.', 'Удавы и питоны. Уход и содержание.', 'Питон для детей.']) == ['Маленький принц.', 'Питон для детей.','Хобби доктора Травена.'])
assert(to_give(['c', 'a', 'b', 'b', 'd', 'a', 'c']) == ['a', 'b', 'c'])

with Tester([]) as t:
    to_give(['Хобби доктора Травена.', 'Маленький принц.', 'Python для детей.'])
    assert len(t) == 0, "функция ничего не должна печатать"

print("Окей!")

Задача 6

Напишите функцию ListMax(L1, L2), которая принимает на вход два списка чисел L1, L2и возвращает наибольшее число из этих двух списков. Склеивать списки (приписывать элементы одного списка в конец другого) нельзя, использовать функцию max() можно. Функция не должна ничего печатать (выводить на экран).

Примеры работы функции:

Применение:

ListMax([6, 8, 9], [7, 10, 2, 5])

Результат:

10

Применение:

ListMax([0, 8, 1, 7], [8, 3, 4, 0, 5, -1])

Результат:

8    
In [ ]:
# YOUR CODE HERE
In [ ]:
assert(ListMax([6, 8, 9], [7, 10, 2, 5]) == 10)
assert(ListMax([0, 8, 1, 7], [8, 3, 4, 0, 5, -1]) == 8)
assert(ListMax([10, 1.5, 3.6], [7.8, 10.2, 2.4, 5.66]) == 10.2)
assert(ListMax([12, 13, 67, 100], [200]) == 200)

with Tester([]) as t:
    ListMax([6, 8, 9], [7, 10, 2, 5])
    assert len(t) == 0, "функция ничего не должна печатать"

print("Окей!")

Задача 7

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

Пример работы функции:

Применение:

my_merge('Ветер', 'надежды', 'держит', 'парус', 'на рассвет', ',', 'и')

Результат:

'Ветер надежды держит парус на рассвет , и'
In [ ]:
# YOUR CODE HERE
In [ ]:
assert(my_merge('Ветер', 'надежды', 'держит', 'парус', 'на рассвет', ',', 'и') == 'Ветер надежды держит парус на рассвет , и')
assert(my_merge('and', 'this','will','last','forever') == 'and this will last forever')
assert(my_merge('не', 'знаю', ',', 'что', ' и ', 'придумать') == 'не знаю , что  и  придумать')

with Tester([]) as t:
    my_merge('and', 'this','will','last','forever')
    assert len(t) == 0, "функция ничего не должна печатать"

print("Окей!")

Задача 8

Напишите функцию text_norm(text, code), которая

  • принимает на вход два аргумента: текст (строка) и код действия (целое число)
  • в случае, если код равен 1, текст возвращается "как есть", без изменений
  • в случае, если код равен 2, текст возвращается в предобработанном виде: в нижнем регистре, без лишних пробелов в начале и в конце.

Функция не должна ничего печатать (выводить на экран).

Примеры работы функции:

Применение:

text_norm(" Don't stop me now  ", 1)

Результат:

' Don't stop me now  '

Применение:

text_norm(" Don't stop me now  ", 2)

Результат:

'don't stop me now'
In [ ]:
# YOUR CODE HERE
In [ ]:
assert(text_norm(" Don't stop me now  ", 1) == " Don't stop me now  ")
assert(text_norm(" Don't stop me now  ", 2) == "don't stop me now")
assert(text_norm('AAA b CC dd', 2) == 'aaa b cc dd')
assert(text_norm('AAA b CC dd', 1) == 'AAA b CC dd')

with Tester([]) as t:
    text_norm(" Don't stop me now  ", 1)
    assert len(t) == 0, "функция ничего не должна печатать"

print("Окей!")

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

Дан словарь cols с соответствиями цветов при переводе изображения в негатив (очень примерно):

cols = {'white': 'black', 'red' : 'green', 'yellow': 'blue'}

Напишите функцию RevertCol(L), которая принимает на вход список цветов L, используемых в изображении, и возвращает список цветов этого изображения, переведенного в негатив. Словарь cols менять нельзя! Функция не должна ничего печатать (выводить на экран).

Примеры работы функции:

Применение:

RevertCol(['white', 'red', 'black', 'green', 'yellow', 'blue'])

Результат:

 ['black', 'green', 'white', 'red', 'blue', 'yellow']
In [ ]:
# YOUR CODE HERE
In [ ]:
assert(RevertCol(['white', 'red', 'black', 'green', 'yellow', 'blue']) == ['black', 'green', 'white', 'red', 'blue', 'yellow'])
assert(RevertCol(['red', 'white']) == ['green', 'black'])
assert(RevertCol(['black', 'black', 'yellow', 'blue']) == ['white', 'white', 'blue', 'yellow'])

with Tester([]) as t:
    RevertCol(['red', 'white']) == ['green', 'black']
    assert len(t) == 0, "функция ничего не должна печатать"

print("Окей!")

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

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

Получить строку со знаками препинания можно так:

import string
string.punctuation
In [ ]:
# YOUR CODE HERE
In [ ]:
mytexts = [
    ("My mind is clearer now. At last all too well I can see where we all soon will be. If you strip away the myth from the man, You will see where we all soon will be.", 
     ['my', 'mind', 'is', 'clearer', 'now', 'at', 'last', 'all', 'too', 'well', 'i', 'can', 'see', 'where', 'we', 'all', 'soon', 'will', 'be', 'if', 'you', 'strip', 'away', 'the', 'myth', 'from', 'the', 'man', 'you', 'will', 'see', 'where', 'we', 'all', 'soon', 'will', 'be']),
    ("I asked him to say what had happened,How it all began I asked again - he never said a word.As if he hadn't heard.",
     ['i', 'asked', 'him', 'to', 'say', 'what', 'had', 'happenedhow', 'it', 'all', 'began', 'i', 'asked', 'again', 'he', 'never', 'said', 'a', 'wordas', 'if', 'he', 'hadnt', 'heard']),
    ("There's too many of you...Don't push me.There's too little of me...Don't crowd me.Heal yourselves!",
    ['theres', 'too', 'many', 'of', 'youdont', 'push', 'metheres', 'too', 'little', 'of', 'medont', 'crowd', 'meheal', 'yourselves']),
    ("   Просто   много лишних  пробелов  ", ['просто', 'много', 'лишних', 'пробелов']),
    ("Есть множество! правил? которые нужно? выучить; но я их держу в голове.",
    ['есть', 'множество', 'правил', 'которые', 'нужно', 'выучить', 'но', 'я', 'их', 'держу', 'в', 'голове'])]
           
for t in mytexts:
    assert(normalize(t[0]) == t[1])
    
with Tester([]) as t:
    normalize("short text!ever")
    assert len(t) == 0, "функция ничего не должна печатать"

print("Окей!")

Задача 11 (5 баллов)

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

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

Считайте, что квадратное уравнение уже приведено к стандартному виду:

$$ax^2+bx+c=0$$

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

Можно: создавать вспомогательные функции внутри основной функции eq_solve(), использовать условия, циклы, методы для строк, списков и прочие объекты, обсуждаемые на лекциях.

Примеры работы функции:

Применение:

eq_solve('1x^2+6x+9=0')

Вывод на экран:

Уравнение имеет одно решение

Возвращаемый результат:

[-3.0]

Применение:

eq_solve('-2x^2-6x+9=0')

Вывод на экран:

Уравнение имеет два решения

Возвращаемый результат:

[-4.098076211353316, 1.098076211353316]

Применение:

eq_solve('3x^2-1x+10=0')

Вывод на экран:

Уравнение имеет только комплексные корни

Возвращаемый результат:

[]
In [ ]:
# YOUR CODE HERE
In [ ]:
tests = [('3x^2-1x+10=0', []), 
         ('-5x^2+10x+1=0', [-0.09544511501033223, 2.0954451150103326]), 
         ('9x^2+4x+4=0', []), 
         ('-10x^2+25x-4=0', [0.1718070673576088, 2.3281929326423914]), 
         ('11x^2+5x-2=0', [0.25591571876066593, -0.7104611733061205]), 
         ('-5x^2-5x+7=0', [-1.784523257866513, 0.7845232578665129]),
         ('17x^2-5x-7=0', [0.8053832142823351, -0.5112655672235116]),
         ('3x^2+18x+27=0', [-3.0])]

for t in tests:
    assert(eq_solve(t[0]) == t[1])


with Tester([]) as t:
    x = eq_solve('3x^2+18x+27=0')
    assert len(t) == 1, "функция должна выводить ровно 1 строку"