Семинары ведут: Щуров И.В., Будылин Р.Я., НИУ ВШЭ
Данный notebook является набором задач по курсу «Программирование на языке Python для сбора и анализа данных» (НИУ ВШЭ, 2014-15). Распространяется по лицензии CC BY-SA 4.0. На странице курса находятся другие материалы.
За разные задачи можно получить разное число баллов. Максимум за ДЗ можно набрать 8 баллов. Вы можете решить больше задач, чем требуется, чтобы набрать 8 баллов, чтобы подстраховаться.
Для предварительной проверки задания нужно скачать данный ipynb
-файл на свой компьютер, открыть его в IPython Notebook/Jupyter (подробнее о том, как это сделать, см. здесь) и вставить решение каждой задачи в ячейку для кода, следующую за его условием, запустить эту ячейку, а затем запустить следующую ячейку (в ней содержится тест). Если запуск ячейки с тестом не приводит к появлению ошибки (assertion), значит, всё в порядке, задача решена. Если приводит к появлению ошибки, значит, тест не пройден и нужно искать ошибку.
Чтобы сдать ДЗ, его надо будет загрузить на сервер в виде ipynb
-файла. Куда загрузить — мы скажем дополнительно чуть позже.
# Внесите решение в эту ячейку
from random import shuffle, seed
seed(0)
def shuffle_test(f, inp, outp, n=10):
for i in range(n):
shuffle(inp)
assert abs(f(*inp)-outp)<1E-15
def test(inp,outp, n=10):
return shuffle_test(median, inp, outp)
test([1,2],1.5)
test([1,2,3], 2)
test([10,20,30],20)
test([10,20,30,40], 25)
test([1, 2, 4, 8, 16], 4)
test([4],4)
test([4]*100+[1000],4)
del shuffle, seed, shuffle_test, test
Написать функцию first_str(str1, str2, ...)
, принимающую на вход несколько строчек и возвращающую ту из них, которая будет идти первой при упорядочивании по алфавиту.
Подсказка. Хотите отсортировать весь список и взять его первый элемент? Это не самое лучшее решение: для сортировки всего списка понадобится много времени, если он большой, а вас интересует лишь самый «маленький» его элемент. Попробуйте исползовать функцию min()
— посмотрите, можно ли ей скормить строки вместо чисел. Исползовать библиотеки нельзя.
# Внесите решение в эту ячейку
from random import shuffle, seed
seed(0)
def shuffle_test(f, inp, outp, n=10):
for i in range(n):
shuffle(inp)
assert f(*inp)==outp
def test(inp,outp, n=10):
return shuffle_test(first_str, inp, outp)
test(['Hello'], 'Hello')
test(['Hello', 'World'], 'Hello')
test(['hello', 'World'], 'World')
test(['a','b','c','d','e'], 'a', 20)
test(['hello']*100+['World'], 'World')
test(['a', 'aa', 'aaa','aaaa'], 'a')
del shuffle, seed, shuffle_test, test
Написать функцию get_first_student_grade(students)
, принимающую на вход список students
, каждый элемент которого является кортежем: первый элемент кортежа является именем студента, а второй его оценкой. Например: students = [('Bob', 3), ('Alice', 4)]
. Функция должна вернуть оценку студента, имя которого является первым при алфавитной сортировке. (В нашем случае должна вернуть число 4
.) Все студенты имеют разные имена.
Подсказка. См. подсказку к задаче B. Возможно, функции min()
удастся скормить кортежи? Попробуйте! Кстати, задача решается ровно в одну строчку (не считая def
). Использовать библиотеки нельзя.
# Внесите решение в эту ячейку
from random import shuffle, seed
seed(0)
def shuffle_test(f, inp, outp, n=10):
for i in range(n):
shuffle(inp)
assert f(inp)==outp
def test(inp,outp, n=10):
return shuffle_test(get_first_student_grade, inp, outp)
test([('Bob', 3), ('Alice', 4)], 4)
test([('Zzz', 1)], 1)
test([('Haha', 2), ('Hoho', 3), ('Zzz', 4), ('aaaa', 5)], 2)
del shuffle, seed, shuffle_test, test
Написать функцию get_name_of_best_student(students)
, принимающую на вход список students
, каждый элемент которого является кортежем: первый элемент кортежа является именем студента, а второй его оценкой. Например: students = [('Bob', 3), ('Alice', 4)]
. Функция должна вернуть имя студента с наибольшей оценкой. Если таких студентов несколько, она должна вернуть имя того из них, кто первый встречается в списке students
(в том порядке, в котором этот список передан). Например, для списка [('Bob', 4), ('Alice', 4)]
необходимо вернуть 'Bob'
, а для списка [('Alice', 4), ('Bob', 4)]
вернуть 'Alice'
.
Подсказка. У функций min()
и max()
есть необязательный параметр key
, работающий так же, как и у функции sort()
. К чему бы это? Кстати, задача снова решается в одну строчку (не считая import
и def
), без циклов и условных операторов. Можно использовать import
.
# Внесите решение в эту ячейку
assert get_name_of_best_student([('Bob', 4), ('Alice', 4)]) == 'Bob'
assert get_name_of_best_student([('Alice', 4), ('Bob', 4)]) == 'Alice'
assert get_name_of_best_student([('Zzz', 3), ('Bob', 4), ('Alice', 4)]) == 'Bob'
assert get_name_of_best_student([('Alice', 4), ('Zzz', 3), ('Bob', 4)]) == 'Alice'
assert get_name_of_best_student([('Zzz', 5), ('Bob', 4), ('Alice', 4)]) == 'Zzz'
assert get_name_of_best_student([('Alice', 4), ('Zzz', 5), ('Bob', 4)]) == 'Zzz'
assert get_name_of_best_student([('Alice', 4), ('Zzz', 5), ('Bob', 4), ('Zzz', 5)]) == 'Zzz'
assert get_name_of_best_student([('Alice', 4), ('Zzz', 5), ('Bob', 4), ('Zzz', 3)]) == 'Zzz'
assert get_name_of_best_student([('Alice', 0)]) == 'Alice'
Написать функцию sort_gradebook(gradebook)
, принимающую на вход некую ведомость в виде списка, элементами которого являются списки такого вида: [first_name, last_name, grade_1, grade_2, ..., grade_n, final_grade]
, где first_name
— имя студента, last_name
— его фамилия, grade_1, ..., grade_n
— оценки студента по контрольным от 1 до n (число n — общее число контрольных, оно одинаковое для конкретного gradebook, но заранее не известно), final_grade
— итоговая оценка. Функция должна отсортировать gradebook
следующим образом (и вернуть его отсортированным):
Примеры см. в тестах.
Подсказка. Внимательное чтение конспекта лекции №6 вам поможет.
# Внесите решение в эту ячейку
from itertools import permutations
def test_sort(inp, outp):
for i in permutations(inp):
assert sort_gradebook(list(i)) == outp
test_sort([
['Alice', 'Smith', 2, 3, 4],
['John', 'Smith', 2, 3, 5]
], [
['John', 'Smith', 2, 3, 5],
['Alice', 'Smith', 2, 3, 4]
])
test_sort([
['Alice', 'Smith', 2, 3, 4],
['John', 'Smith', 2, 3, 4]
], [
['Alice', 'Smith', 2, 3, 4],
['John', 'Smith', 2, 3, 4]
])
test_sort([
['Alice', 'Smith', 1, 3, 4],
['John', 'Smith', 2, 3, 4]
], [
['John', 'Smith', 2, 3, 4],
['Alice', 'Smith', 1, 3, 4]
])
test_sort([
['Alice', 'Smith', 1, 1, 1, 3, 4],
['John', 'Smith', 1, 1, 2, 3, 4]],
[
['John', 'Smith', 1, 1, 2, 3, 4],
['Alice', 'Smith', 1, 1, 1, 3, 4]
])
test_sort([
['Alice', 'Doe', 1, 1, 3, 3, 4],
['Alice', 'Smith', 1, 1, 3, 3, 4],
['John', 'Smith', 1, 1, 2, 3, 4]],
[
['Alice', 'Doe', 1, 1, 3, 3, 4],
['Alice', 'Smith', 1, 1, 3, 3, 4],
['John', 'Smith', 1, 1, 2, 3, 4]
])
test_sort([
['Alice', 'Doe', 1, 1, 3, 3, 4],
['Alice', 'Smith', 1, 1, 3, 3, 4],
['John', 'Smith', 2, 1, 2, 3, 4]],
[
['John', 'Smith', 2, 1, 2, 3, 4],
['Alice', 'Doe', 1, 1, 3, 3, 4],
['Alice', 'Smith', 1, 1, 3, 3, 4],
])
del test_sort
Написать функцию mail(student, grade, perf)
, возвращающую строку со следующим текстом: "Dear <student>! Your grade is <grade> and your performance rate is <perf>%"
. Здесь student
— имя студента, grade
— его оценка, являющаяся целым числом, а perf
— вещественное число, которое необходимо вывести с двумя знаками после точки. Если perf
целое, оно всё равно должно быть выведено как вещественное число с двумя знаками после точки. (Последний знак процента — это просто знак процента.)
# Внесите решение в эту ячейку
assert mail("Nick", 5, 12) == 'Dear Nick! Your grade is 5 and your performance rate is 12.00%'
assert mail("John", 4, 22.22) == 'Dear John! Your grade is 4 and your performance rate is 22.22%'
assert mail("Alice", 12, 1.2345) == 'Dear Alice! Your grade is 12 and your performance rate is 1.23%'
assert mail("Elizabeth", 14, 1.235) == 'Dear Elizabeth! Your grade is 14 and your performance rate is 1.24%'
Написать функцию pi_digits(n)
, возвращающую число $\pi$ в виде строки с n
знаками после десятичной точки, где n
— целое число от 0 до 15.
Подсказка. Число pi
можно импортировать из math
.
# Внесите решение в эту ячейку
out = ['3', '3.1', '3.14', '3.142', '3.1416', '3.14159', '3.141593', '3.1415927', '3.14159265',
'3.141592654', '3.1415926536', '3.14159265359', '3.141592653590', '3.1415926535898',
'3.14159265358979', '3.141592653589793']
for i,s in enumerate(out):
assert pi_digits(i) == s