Наука о данных

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

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

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

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

Чтобы сдать ДЗ, его надо загрузить в 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), которая бы с помощью API nominatim находила координаты двух городов, заданных строками place1 и place2, и возвращала бы число с плавающей точкой, являющееся ответом на вопрос: на сколько градусов place2 севернее, по сравнению с place1?

Подсказка. Мы будем считать городами объекты, которые имеют тип city или town.

In [ ]:
"# YOUR CODE HERE"
In [ ]:
import time

assert abs(diff_lat("Москва", "Апатиты") - 11.81) < 0.1
time.sleep(1)
assert abs(diff_lat("Краснодар", "Петропавловск-Камчатский") - 8) < 0.1
time.sleep(1)
assert abs(diff_lat("Геленджик", "Саратов") - 7) < 0.1
time.sleep(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 (1 балл)

С помощью API Teleport можно получить различную информацию о качестве жизни в ряде городских областей (urban areas). Однако, чтобы получить информацию про конкретную область, нужно сперва узнать её идентификатор. Для этого мы хотим запросить список всех областей, обратившись к адресу https://api.teleport.org/api/urban_areas/, и сделать словарь, у которого ключами являются города, а значениями — URL'ы, по которым можно получить дополнительную информацию о данной области. Напишите функцию teleport_urban_areas_city_to_url(), возвращающую такой словарь.

In [ ]:
"# YOUR CODE HERE"
In [ ]:
dct = teleport_urban_areas_city_to_url()
assert dct["Aarhus"] == "https://api.teleport.org/api/urban_areas/slug:aarhus/"
assert (
    dct["Dar es Salaam"]
    == "https://api.teleport.org/api/urban_areas/slug:dar-es-salaam/"
)
assert dct["St. Louis"] == "https://api.teleport.org/api/urban_areas/slug:st-louis/"
assert (
    dct["Washington, D.C."]
    == "https://api.teleport.org/api/urban_areas/slug:washington-dc/"
)

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

Теперь нужно написать функцию teleport_scores(cities, fields), принимающую на вход список городов cities и список критериев fields и возвращающую датафрейм, у которого по строкам идут города, а в каждой строке записано, сколько очков получил город по данному критерию согласно данным Teleport. Пример, как можно получить искомую информацию про данную область, можно найти в документации (см. раздел INCOME, LIVING COSTS & QUALITY OF LIFE DATA). Индексами строк должны быть названия городов. Можно (и нужно) использовать функцию, написанную в предыдущей задаче.

In [ ]:
"# YOUR CODE HERE"
In [ ]:
from pandas.testing import assert_frame_equal

assert_frame_equal(
    teleport_scores(
        ["Moscow", "Washington, D.C."], ["Housing", "Business Freedom", "Taxation"]
    ),
    pd.DataFrame(
        {
            "Housing": {
                "Moscow": 6.555000000000001,
                "Washington, D.C.": 1.2105000000000001,
            },
            "Business Freedom": {
                "Moscow": 5.386666666666667,
                "Washington, D.C.": 8.671,
            },
            "Taxation": {"Moscow": 6.017000000000001, "Washington, D.C.": 4.062},
        }
    ),
    check_names=False,
)

assert_frame_equal(
    teleport_scores(
        ["Moscow", "Washington, D.C.", "Dar es Salaam", "Baku"],
        ["Housing", "Business Freedom", "Taxation", "Internet Access"],
    ),
    pd.DataFrame(
        {
            "Housing": {
                "Moscow": 6.555000000000001,
                "Washington, D.C.": 1.2105000000000001,
                "Dar es Salaam": 7.652000000000001,
                "Baku": 9.745000000000001,
            },
            "Business Freedom": {
                "Moscow": 5.386666666666667,
                "Washington, D.C.": 8.671,
                "Dar es Salaam": 3.2886666666666664,
                "Baku": 5.671666666666666,
            },
            "Taxation": {
                "Moscow": 6.017000000000001,
                "Washington, D.C.": 4.062,
                "Dar es Salaam": 4.497000000000001,
                "Baku": 5.861,
            },
            "Internet Access": {
                "Moscow": 6.571,
                "Washington, D.C.": 3.825500000000001,
                "Dar es Salaam": 1.11,
                "Baku": 1.4420000000000002,
            },
        }
    ),
    check_names=False,
)
In [ ]: