Статистика и открытые данные

И. В. Щуров, НИУ ВШЭ

Авторы задач в подборке: А. Зотов, И. Щуров.

На странице курса находятся другие материалы.

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

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

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

  1. Скачать данный ipynb-файл на свой компьютер, открыть его в IPython Notebook/Jupyter.
  2. Запустить ячейку, в которую вы вставили код с решением.
  3. Запустить следующую ячейку (в ней содержится тест). Если запуск ячейки с тестом не приводит к появлению ошибки (assertion), значит, всё в порядке, задача решена. Если приводит к появлению ошибки, значит, тест не пройден и нужно искать ошибку.

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

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

In [ ]:
import pandas as pd #Поехали!
import numpy as np
import requests

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

С помощью API World Bank, напишите функцию get_capital(country_code), принимающую на вход ISO 3166-1 код государства и возвращающую название его столицы (в том виде, в котором оно возвращается этим API). Если вы хотите, чтобы API использовало формат JSON, укажите словарь {'format':'json'} в качестве второго аргумента requests.get. (Вы можете использовать как JSON, так и XML-интерфейс, на ваш выбор.) Обратите внимание: код страны здесь надо передавать как часть URL.

Подсказка. Если вы будете использовать XML-API, под некоторыми операционными системами вам может потребоваться указать кодировку utf-8-sig. Это можно сделать, устанавливая атрибут encoding у объекта, возвращаемого requests.get (т.е. написать что-то вроде r.encoding = 'utf-8-sig').

In [ ]:
# YOUR CODE HERE
In [ ]:
assert get_capital("rus") == 'Moscow'
assert get_capital("usa") == 'Washington D.C.'
assert get_capital('bra') == 'Brasilia'
assert get_capital('it') == 'Rome'

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

Написать функцию diff_lat(place1, place2), которая бы с помощью геокодера Яндекса находила координаты двух объектов, заданных строками place1 и place2, и возвращала бы число с плавающее точкой, являющееся ответом на вопрос: на сколько градусов place2 севернее, по сравнению с place1?

In [ ]:
# YOUR CODE HERE
In [ ]:
assert abs(diff_lat("Москва", "Апатиты") - 11.81) < 0.1
assert abs(diff_lat("Шаболовка, 26", "Кочновский, 3")-0.086) < 0.001
assert abs(diff_lat("Краснодар", "Петропавловск-Камчатский") - 8) < 0.1
assert abs(diff_lat("Геленджик", "Саратов") - 7) < 0.1
assert abs(diff_lat("Саратов", "Геленджик") + 7) < 0.1

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

Напишите функцию check_email(email), которая принимает на вход адрес электронной почты и с помощью University Domains and Names API определяет, к какому университету и какой стране относится адрес. Программа должна вернуть строку формата Affiliated with %University Name% in %Country%, если адрес относится к какому-то университету, и Not a university email иначе. К примеру, для запроса check_email([email protected]) программа должна вернуть строку Affiliated with New Economic School in Russian Federation.

Подсказка: Вам не нужно скачивать весь двухмегабайтный json-файл с сервера. Поиск http://universities.hipolabs.com/search поддерживает запросы типа domain=hse.ru.

In [ ]:
# YOUR CODE HERE
In [ ]:
assert check_email('[email protected]') == 'Affiliated with New Economic School in Russian Federation'
assert check_email('[email protected]') == 'Affiliated with Higher School of Economics in Russian Federation'
assert check_email('[email protected]') == 'Not a university email'
assert check_email('[email protected]') == 'Not a university email'
assert check_email('[email protected]') == 'Affiliated with Stanford University in United States'
assert check_email('[email protected]') == 'Affiliated with Charles University Prague in Czech Republic'

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

На сайте http://dronestre.am собираются данные об ударах дронов США. У него есть простое API, позволяющее получить информацию о каждом ударе в виде JSON-файла. Адрес для API: http://api.dronestre.am/data Написать функцию strikes_per_country(year), принимающую на вход год в виде целого числа (например, 2015) и возвращающую словарь, ключами которого являются страны, а значениями — число ударов в этой стране.

Подсказка 1. API не принимает параметр year (и вообще никаких параметров не принимает). Вам придётся скачать все данные и вытащить из них только те записи, которые вам нужны. Дата в данных указана в виде строки в стандартном формате. Можно проверить, что строка начинается с некоторого префикса с помощью .startswith. Например, "Hello".startswith("He") возвращает True.

Подсказка 2. Попробуйте использовать collections.Counter (from collections import Counter). Почитайте в документации, что он делает.

Подсказка 3. Для ускорения работы функции вы можете записать код, который будет запрашивать информацию с сайта, до описания функции:

# (make request)
# json_data = (some lines to get data)
def strikes_per_country(year):
    # query json_data for data you need
In [ ]:
# YOUR CODE HERE
In [ ]:
assert strikes_per_country(2002) == {'Yemen': 1}
assert strikes_per_country(2009) == {'Pakistan': 56}
assert strikes_per_country(2016) == {'Pakistan': 3, 'Somalia': 5, 'Yemen': 23}

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

С помощью API Google Books можно получать информацию о различных книгах. Например, вот так можно получить данные по книге по её ISBN: https://www.googleapis.com/books/v1/volumes?q=isbn:9785699648146. Напишите функцию book_table(isbns), принимающую на вход список ISBN'ов и возвращающую таблицу pandas, содержащую заглавие, авторов, язык и число страниц. Названия колонок должны соответствовать названиям полей в ответе API. Если авторов несколько, они должны быть разделены запятой и пробелом. Пример см. в тесте.

In [ ]:
# YOUR CODE HERE
In [ ]:
obtained = book_table(['9781292153964', '9780262035613', '9785457499850'])
expected = pd.DataFrame({'authors': {0: 'Stuart Russell, Peter Norvig',
  1: 'Ian Goodfellow, Yoshua Bengio, Aaron Courville',
  2: 'Рэй Брэдбери'},
 'language': {0: 'en', 1: 'en', 2: 'ru'},
 'pageCount': {0: 1152, 1: 800, 2: 499},
 'title': {0: 'Artificial Intelligence',
  1: 'Deep Learning',
  2: 'Вино из одуванчиков'}})
assert obtained.to_dict() == expected.to_dict()