Книга Изучаем Python
Скачать 4.68 Mb.
|
359 import pygal from pygal.style import RotateStyle # Группировка стран по 3 уровням населения. cc_pops_1, cc_pops_2, cc_pops_3 = {}, {}, {} for cc, pop in cc_populations.items(): if pop < 10000000: wm_style = RotateStyle('#336699') wm = pygal.Worldmap(style=wm_style) wm.title = 'World Population in 2010, by Country' Стили Pygal хранятся в модуле style , из которого программа импортирует стиль RotateStyle . Этот класс получает один аргумент — цвет RGB в шестнадцатерич- ном формате . Затем Pygal выбирает цвета каждой группы на основании пере- данного цвета. Цвет в шестнадцатеричном формате представляет собой строку из символа решетки ( # ), за которым следуют шесть символов: первые два пред- ставляют красную составляющую цвета, следующие два — зеленую и последние два — синюю. Значения составляющих лежат в диапазоне от 00 (нулевая интен- сивность) до FF (максимальная интенсивность). В Интернете можно легко найти приложение для экспериментов с цветами и получения соответствующих значений RGB. Цвет, используемый в данном случае ( #336699 ), содержит немного красного (33), чуть больше зеленого (66) и еще больше синего (99). В результате RotateStyle назначается светло-синий базовый цвет для выполнения дальнейших операций. RotateStyle возвращает объект стиля, который сохраняется в переменной wm_style Чтобы использовать объект стиля, передайте его в именованном аргументе при соз- дании экземпляра Worldmap . На рис. 16.11 изображена обновленная диаграмма. Рис. 16.11. Три уровня численности населения в общей цветовой теме 360 Глава 16 • Загрузка данных Стилевое оформление придает карте целостный внешний вид с хорошо различи- мыми группами. Осветление темы По умолчанию Pygal использует темные темы оформления. Для печати я осветлил стиль своих диаграмм при помощи класса LightColorizedStyle . Этот класс изме- няет общую тему оформления диаграммы, включая фон и метки, а также цвета от- дельных стран. Чтобы использовать его, сначала необходимо импортировать стиль: from pygal.style import LightColorizedStyle Затем вы сможете использовать LightColorizedStyle в программе: wm_style = LightColorizedStyle Однако этот класс не позволяет напрямую управлять используемым цветом, поэто- му Pygal выбирает базовый цвет по умолчанию. Чтобы назначить цвет, используйте LightColorizedStyle в качестве базового стиля для RotateStyle . Импортируйте LightColorizedStyle и RotateStyle : from pygal.style import LightColorizedStyle, RotateStyle Создайте стиль с использованием RotateStyle , но передайте дополнительный аргумент base_style : wm_style = RotateStyle('#336699', base_style=LightColorizedStyle) В результате для карты используется светлая общая тема, но цвета стран выбирают- ся на основе цвета, переданного в аргументе. При использовании этого стиля ваши диаграммы будут больше похожи на снимки экрана на иллюстрациях. Пока вы экспериментируете с поиском стилевых директив, хорошо подходящих для тех или иных визуализаций, попробуйте использовать псевдонимы в командах import : from pygal.style import LightColorizedStyle as LCS, RotateStyle as RS Определения стилей с псевдонимами получаются более короткими: wm_style = RS('#336699', base_style=LCS) Как видите, даже небольшой набор стилевых директив открывает широкие воз- можности для управления внешним видом диаграмм и карт в Pygal. УПРАЖНЕНИЯ 16-5 . Все страны: на картах, построенных в этом разделе, наша программа не смогла автоматически найти двухбуквенные коды примерно для 12 стран . Определите, что это за страны, и найдите коды в словаре COUNTRIES . Добавьте блок if-elif в get_country_code(), чтобы функция возвращала правильные коды для этих конкретных стран: if country_name == 'Yemen, Rep.' return 'ye' elif ... Итоги 361 Разместите этот код после цикла COUNTRIES, но перед командой return None . Когда это будет сделано, карта станет более полной . 16-6 . Валовый внутренний продукт: Фонд Open Knowledge Foundation предоставляет на- бор данных с величиной валового внутреннего продукта (ВВП) по каждой стране мира; его можно загрузить по адресу http://data .okfn .org/data/core/gdp/ . Загрузите версию этого набора данных в формате JSON и нанесите на карту ВВП каждой страны мира за самый по- следний год в наборе данных . 16-7 . Выберите данные самостоятельно: Всемирный банк предоставляет различные наборы данных, разбитые по странам . Откройте страницу http://data .worldbank .org/indicator/ и най- дите набор данных, который покажется вам интересным . Щелкните на наборе данных, щелкните по ссылке Download Data и выберите формат CSV . Вы получите три файла CSV, два из которых снабжены пометкой Metadata; используйте третий файл CSV . Напишите про- грамму для генерирования словаря; ключами словаря являются двухбуквенные коды стран Pygal, а значениями — выбранные вами данные из файла . Нанесите данные на диаграмму Worldmap и оформите карту на свое усмотрение . 16-8 . Тестирование модуля country_codes: во время разработки модуля country_codes мы использовали команды print для проверки работоспособности функции get_country_code() . Напишите нормальный тест для этой функции, используя информацию из главы 11 . Итоги В этой главе вы научились работать с сетевыми наборами данных. Вы узнали, как обрабатывать файлы CSV и JSON и как извлечь данные, на которых вы хотите со- средоточиться. Используя реальные погодные данные, вы освоили новые возмож- ности работы с библиотекой matplotlib, включая использование модуля datetime и возможность нанесения нескольких наборов данных на одну диаграмму. Вы узнали, как нанести данные на карту мира с использованием Pygal и как изменить оформление карт и диаграмм Pygal. С накоплением опыта работы с файлами CSV и JSON вы сможете обрабатывать практически любые данные, которые вам потребуется проанализировать. Многие сетевые наборы данных могут загружаться хотя бы в одном из этих форматов. По- сле работы с этими форматами вам также будет проще усвоить другие форматы данных. В следующей главе вы напишете программы для автоматического сбора данных из сетевых источников, а затем создадите визуализации этих данных. Это занятие весьма интересное, если вы рассматриваете программирование как увлечение, и абсолютно необходимое, если вы занимаетесь программированием профессио- нально. 17 Работа с API В этой главе вы научитесь писать специализированные программы для построения визуализаций на основании загруженных ими данных. Ваша программа будет ис- пользовать программный интерфейс (API) веб-приложения для автоматического запроса конкретной информации с сайта (вместо целых страниц). Полученная информация будет использоваться для построения визуализации. Так как про- граммы, написанные по такой схеме, всегда используют самые свежие данные для построения визуализации, даже при быстро изменяющихся данных полученная диаграмма всегда будет оставаться актуальной. Использование API веб-приложений API веб-приложения представляет собой часть веб-сайта, предназначенную для взаимодействия с программами, которые используют особым образом построенные URL-адреса для запроса информации. Подобные запросы называются вызовами API. Запрашиваемые данные возвращаются в удобном формате (например, JSON или CSV). Многие приложения, зависящие от внешних источников данных (как приложения, интегрирующиеся с сайтами социальных сетей), используют вызовы API. Git и GitHub Наша визуализация будет построена на базе информации с GitHub — сайта, органи- зующего совместную работу программистов над проектами. Мы воспользуемся API GitHub для запроса информации о проектах Python и последующего построения интерактивной визуализации относительной популярности этих проектов в Pygal. Имя GitHub (https://github.com/) происходит от Git — распределенной системы управления версиями, которая позволяет программистам совместно трудиться над проектами. Пользователи Git управляют своим индивидуальным вкладом в проект, чтобы изменения, вносимые одним человеком, не конфликтовали с изменениями, вносимыми другими людьми. Когда вы реализуете новую возможность в проекте, Git отслеживает изменения, внесенные в каждый файл. Если новый код успешно работает, вы закрепляете внесенные изменения, и Git записывает новое состояние проекта. Если же вы допустили ошибку и хотите отменить внесенные изменения, Git позволяет легко вернуться к любому из предыдущих рабочих состояний. Использование API веб-приложений 363 (За дополнительной информацией об управлении версиями с использованием Git обращайтесь к приложению Г.) Проекты GitHub хранятся в репозиториях, содер- жащих все ресурсы, связанные с проектом: код, информацию о других участниках, все проблемы или отчеты об ошибках и т. д. Если проект нравится пользователям GitHub, то пользователи могут «поставить звезду», чтобы продемонстрировать свою поддержку и следить за проектами, которые могут им пригодиться. В этой главе мы напишем программу для авто- матической загрузки информации о проектах Python с наибольшим количеством звезд на GitHub, а затем построим содержательную визуализацию таких проектов. Запрос данных с использованием вызовов API GitHub поддерживает API (программный интерфейс) для запроса разнообразной информации посредством вызовов API. Чтобы понять, как выглядит вызов API, введите следующий адрес в адресной строке своего браузера и нажмите Enter: https://api.github.com/search/repositories?q=language:python&sort=stars Этот вызов возвращает количество проектов Python, размещенных на GitHub в на- стоящее время, а также информацию о самых популярных репозиториях Python. Рассмотрим вызов подробнее: первая часть https://api.github.com/ передает за- прос части сайта GitHub, отвечающей на вызовы API. Следующая часть, search/ repositories, приказывает API провести поиск по всем репозиториям в GitHub. Вопросительный знак после repositories означает, что мы собираемся передать аргумент. Символ q обозначает запрос (Query), а знак равенства начинает опре- деление запроса (q=). Выражение language:python указывает, что запрашивается информация только по репозиториям, для которых основным языком указан Python. Завершающая часть, &sort=stars, сортирует проекты по количеству при- своенных им звезд. В следующем фрагменте приведены несколько начальных строк ответа. Вероятно, по виду ответа вы уже поняли, что этот URL-адрес не предназначен для обычных пользователей. { "total_count": 713062, "incomplete_results": false, "items": [ { "id": 3544424, "name": "httpie", "full_name": "jkbrzt/httpie", Как видно из второй строки вывода, на момент написания книги на GitHub было найдено 713 062 проектов Python. Значение "incomplete_results" равно false , а значит, запрос был обработан успешно (информация не является неполной). Если бы у GitHub возникли проблемы с полной обработкой запроса API, то в этом поле было бы возвращено значение true . Возвращаемые данные отображаются в списке "items" с информацией о самых популярных проектах Python на GitHub. 364 Глава 17 • Работа с API Установка пакета requests Пакет requests предоставляет удобные средства для запроса информации с сайтов из программ Python и анализа полученных ответов. Чтобы установить requests , введите команду следующего вида: $ pip install --user requests Если вы еще не использовали pip , обратитесь к разделу «Установка пакетов Python с использованием pip» на с. 227. (Возможно, вам придется использовать другую версию команды в зависимости от конфигурации системы.) Обработка ответа API Теперь мы напишем программу, которая выдает вызов API для поиска на Github проектов Python с наибольшим количеством звезд: python_repos.py import requests # Создание вызова API и сохранение ответа. url = 'https://api.github.com/search/repositories?q=language:python &sort=stars' r = requests.get(url) print("Status code:", r.status_code) # Сохранение ответа API в переменной. response_dict = r.json() # Обработка результатов. print(response_dict.keys()) В точке импортируется модуль requests . В точке URL-адрес вызова API со- храняется в переменной, после чего модуль requests используется для вызова . Мы вызываем метод get() и передаем ему URL, а объект ответа сохраняется в переменной r . Объект ответа содержит атрибут status_code , в котором хранится признак успешного выполнения запроса. (Код 200 — признак успешного ответа.) В точке программа выводит значение status_code , чтобы вы могли убедиться в том, что вызов был обработан успешно. API возвращает информацию в формате JSON, поэтому в программе используется метод json() для преобразования информации в словарь Python. Полученный словарь сохраняется в переменной response_dict Наконец, программа выводит ключи словаря response_dict , и мы видим следу- ющее: Status code: 200 dict_keys(['items', 'total_count', 'incomplete_results']) Код статуса 200 означает, что запрос был обработан успешно. Словарь ответа со- держит всего три ключа: ‘ items ’, 'total_count' и 'incomplete_results' Использование API веб-приложений 365 ПРИМЕЧАНИЕ Подобные простые вызовы должны возвращать полный набор результатов, поэтому значе- ние, связанное с 'incomplete_results’, можно достаточно безопасно игнорировать . Но, если ваша программа выдает более сложные вызовы API, обязательно проверяйте это значение . Работа со словарем ответа Итак, полученная при вызове API информация хранится в словаре, и мы можем заняться работой с данными. Для начала построим сводку с обобщенными сведе- ниями — это позволит убедиться в том, что вызов вернул ожидаемую информацию, и перейти к анализу интересующих данных. python_repos.py import requests # Создание вызова API и сохранение ответа. url = 'https://api.github.com/search/repositories?q=language:python&sort=stars' r = requests.get(url) print("Status code:", r.status_code) # Сохранение ответа API в переменной. response_dict = r.json() print("Total repositories:", response_dict['total_count']) # Анализ информации о репозиториях. repo_dicts = response_dict['items'] print("Repositories returned:", len(repo_dicts)) # Анализ первого репозитория. repo_dict = repo_dicts[0] print("\nKeys:", len(repo_dict)) for key in sorted(repo_dict.keys()): print(key) В точке выводится значение, связанное с 'total_count' , которое представляет общее количество репозиториев Python в GitHub. Значение, связанное с 'items' , представляет собой список со словарями, каждый из которых содержит данные об одном репозитории Python. В точке этот список словарей сохраняется в repo_dicts . Затем программа выводит длину repo_dicts , чтобы пользователь видел, по какому количеству репозиториев имеется инфор- мация. Чтобы получить первое представление об информации, возвращенной по каждому репозиторию, программа извлекает первый элемент из repo_dicts и сохраняет его в repo_dict . Затем программа выводит количество ключей в словаре — это зна- чение определяет объем доступной информации . В точке выводятся все ключи словаря; по ним можно понять, какая информация включена в ответ. Из сводки начинает вырисовываться более четкая картина полученных данных: Status code: 200 Total repositories: 713062 366 Глава 17 • Работа с API Repositories returned: 30 Keys: 68 archive_url assignees_url blobs_url url watchers watchers_count API GitHub возвращает подробную информацию о каждом репозитории: в repo_ dict 68 ключей . Просмотр ключей дает представление о том, какую информацию можно извлечь о проекте. (Чтобы узнать, какую информацию можно получить через API, следует либо прочитать документацию, либо проанализировать инфор- мацию в коде, как мы и поступаем.) Прочитаем значения некоторых ключей repo_dict : python_repos.py # Анализ информации о репозиториях. repo_dicts = response_dict['items'] print("Repositories returned:", len(repo_dicts)) # Анализ первого репозитория. repo_dict = repo_dicts[0] print("\nSelected information about first repository:") print('Name:', repo_dict['name']) print('Owner:', repo_dict['owner']['login']) print('Stars:', repo_dict['stargazers_count']) print('Repository:', repo_dict['html_url']) print('Created:', repo_dict['created_at']) print('Updated:', repo_dict['updated_at']) print('Description:', repo_dict['description']) В программе выводятся значения, связанные с некоторыми ключами словаря пер- вого репозитория. В точке выводится имя проекта. Владельца проекта представ- ляет целый словарь, поэтому в точке ключ owner используется для обращения к словарю, представляющему владельца, после чего ключ login используется для получения регистрационного имени владельца. В точке выводится количество звезд, заработанных проектом, и URL репозитория GitHub проекта. Далее выво- дится дата создания и последнего обновления репозитория . В завершение выводится описание репозитория; вывод должен выглядеть примерно так: Status code: 200 Total repositories: 713065 Repositories returned: 30 Selected information about first repository: Name: httpie Owner: jkbrzt Stars: 16101 Использование API веб-приложений 367 Repository: https://github.com/jkbrzt/httpie Created: 2012-02-25T12:39:13Z Updated: 2015-07-13T14:56:41Z Description: CLI HTTP client; user-friendly cURL replacement featuring intuitive UI, JSON support, syntax highlighting, wget-like downloads, extensions, etc. Из вывода видно, что на момент написания книги самым «звездным» проектом Python на GitHub был проект HTTPie, владельцем которого является пользователь jkbrzt, и звезды этот проект получил более чем от 16 000 пользователей GitHub. Мы видим URL репозитория проекта, дату создания (февраль 2012 г.) и то, что проект недавно обновлялся. Наконец, из описания следует, что HTTPie помогает выдавать вызовы HTTP из терминала (CLI — сокращение от «Command Line Interface», то есть «интерфейс командной строки»). Сводка самых популярных репозиториев При построении визуализации этих данных на диаграмму необходимо нанести более одного репозитория. Напишем цикл для вывода информации о каждом ре- позитории, возвращаемом вызовом API, чтобы все эти репозитории можно было включить в визуализацию: python_repos.py # Анализ информации о репозиториях. repo_dicts = response_dict['items'] print("Repositories returned:", len(repo_dicts)) print("\nSelected information about each repository:") for repo_dict in repo_dicts: print('\nName:', repo_dict['name']) print('Owner:', repo_dict['owner']['login']) print('Stars:', repo_dict['stargazers_count']) print('Repository:', repo_dict['html_url']) print('Description:', repo_dict['description']) В точке выводится приветственное сообщение. В точке перебираются все словари в repo_dicts . Внутри цикла выводится имя каждого проекта, его владелец, количество звезд, URL на GitHub и краткое описание проекта: Status code: 200 Total repositories: 713067 Repositories returned: 30 Selected information about each repository: Name: httpie Owner: jkbrzt Stars: 16101 Repository: https://github.com/jkbrzt/httpie Description: CLI HTTP client; user-friendly cURL replacement featuring intuitive UI, JSON support, syntax highlighting, wget-like downloads, extensions, etc. |