Статьи

Python 101 для начинающих ботаников данных

Первоначально Написал Джон Хэмминк

Как ученый, работающий с данными, или любой, кто заинтересован в сборе данных по этому вопросу, несомненно, полезно знать о том, как собирать данные в вашем приложении — данные, которые вы захотите позднее запрашивать и анализировать.

Здесь мы создадим приложение на Python из AZ, итерируем его, чтобы сделать его более надежным, и, наконец, добавим регистрацию событий приложения с помощью Fluentd и Treasure Data. Мы выбрали Python, потому что он быстро становится языком выбора среди начинающих ученых данных. В наших примерах мы будем использовать Python версии 2.7.

В следующем разделе мы рассмотрим еще больше языков программирования и сред, а также визуализацию (используя такие инструменты, как Tableau и Chartio), но сейчас давайте начнем с изучения некоторых основ Python, прежде чем перейти к сбору данных.

Камень, ножницы … бумага?

Для нашего примера сегодня мы создадим базовое приложение « камень, бумага, ножницы» . (Что касается вас, ищущих работу, то это может или не может быть тем, о чем вас спросят в случайном интервью по кодированию, поэтому обратите внимание!) С его помощью мы будем собирать данные о:

  • игрок
  • Выбор
  • решение суда

Для тех из вас, кто не знаком с концепцией Rock-Paper-Scissors, давайте спросим Википедию :

Камень-ножницы-бумага … — это игра с нулевой суммой, в которой каждый игрок одновременно формирует одну из трех фигур вытянутой рукой. Этими формами являются «камень» (простой кулак), «бумага» (плоская рука) и «ножницы» (кулак с указательным и средним пальцами, образующими букву V). В игре есть только три возможных результата, кроме ничьей: игрок, решивший сыграть в рок, побьет другого игрока, выбравшего ножницы («ножницы для дробления камня»), но проиграет тому, кто играл в бумагу («бумага покрывает камень») ; игра бумаги проиграет игре ножниц («ножницы режут бумагу»). Если оба игрока бросают одну и ту же фигуру, игра завязывается и обычно сразу переигрывается, чтобы разорвать ничью.

Что касается меня, я изучил игру, наблюдая, как несколько детей играют в нее на улице перед моим домом. Возможно, также было проведено собеседование по кодированию.

Основное приложение

import random

tie= "a tie"
p1 = "Player 1; Player 2 loses"
p2 = "Player 2; Player 1 loses"

myDict = {('rock', 'rock') : tie, ('rock', 'paper') : p2,
('rock', 'scissors') : p1, ('paper', 'rock') : p1, ('paper', 'paper') : tie, ('paper', 'scissors') : p2, ('scissors', 'rock') : p2, ('scissors', 'paper') : p1, ('scissors', 'scissors') : tie }

def throw(player1, player2):
    verdict = myDict[(player1, player2)]
    print "The game goes to " + verdict

print "Ya wanna play Rock, Paper, Scissors?"
player1 = raw_input("Throw!  Choose 'rock', 'paper', or 'scissors': " )
print "Player 1 chooses: " + player1
player2 = random.choice(['rock', 'paper', 'scissors'])
print "Player 2 chooses: " + player2
throw(player1, player2)

Примечание: прокрутите для просмотра полного кода

Листинг 1: rsp.py

Несколько замечаний:

  • В наших целях у нас будет игра игрока против компьютера, поэтому мы будем использовать Python raw_input (), чтобы получить ввод игрока, и random.choice (), чтобы сгенерировать ввод компьютера. Обратите внимание, что мы импортировали случайную библиотеку в начале.
  • Мы будем использовать словарь Python (myDict) для поиска вердикта по паре ключ: значение. Наш ключ к поиску — это пара вариантов player1 и player2. Мы используем функцию throw () для этого поиска и сохраняем наш вердикт в связанной переменной. Кстати, словари, как правило, являются хорошим способом сделать что-то в Python и намного лучше, чем очень длинная строка операторов if… then… else.

Запуск игры с

$ python rsp.py

Производит следующий вывод:

Ya wanna play Rock, Paper, Scissors?
Throw!  Choose ‘rock’, ‘paper’, or ‘scissors': rock
Player 1 chooses: rock
Player 2 chooses: scissors
The game goes to Player 1; Player 2 loses

Интересно отметить, что в настоящее время мы не обрабатываем никаких ошибок. Если мы играем в игру и выбираем что-то кроме камня, бумаги или ножниц, мы получаем ошибку:

Throw!  Choose ‘rock’, ‘paper’, or ‘scissors': moar paper
Player 1 chooses: moar paper
Player 2 chooses: rock
Traceback (most recent call last):
File “rsp.py”, line 21, in <module>
throw(player1, player2)
File “rsp.py”, line 13, in throw
verdict = myDict[(player1, player2)] KeyError: (‘moar paper’, ‘rock’)

Для Эрр … Ну, для Эрр

Давайте справимся с этой ошибкой. Мы переместим входные данные проигрывателя и функцию throw () в блок try / Кроме того, чтобы наше приложение могло восстановиться (и не завершиться сбоем), если пользователь введет неправильный ввод. Мы также вызовем эту функцию, чтобы повторить, если пользователь вводит неправильную вещь:

def lets_get_started():
  try:
     player1 = raw_input("Throw!  Enter 'rock', 'paper', or 'scissors': " )
     print "You chose: " + player1
     player2 = random.choice(['rock', 'paper', 'scissors'])
     print "The computer chose: " + player2
     throw(player1, player2)
  except KeyError:
     print "Hey!  I said enter 'rock', 'paper' or 'scissors'!  Try again."
     lets_get_started()

Отредактируйте ваш файл так, чтобы он выглядел так:

import random

tie= "is a tie"
p1 = "goes to you; the computer loses."
p2 = "goes to the computer; you lose."

myDict = {('rock', 'rock') : tie, ('rock', 'paper') : p2,
('rock', 'scissors') : p1, ('paper', 'rock') : p1, ('paper', 'paper') : tie, ('paper', 'scissors') : p2, ('scissors', 'rock') : p2, ('scissors', 'paper') : p1, ('scissors', 'scissors') : tie }

def throw(player1, player2):
     verdict = myDict[(player1, player2)]
     print "The game " + verdict

def lets_get_started():
  try:
     player1 = raw_input("Throw!  Enter 'rock', 'paper', or 'scissors': " )
     print "You chose: " + player1
     player2 = random.choice(['rock', 'paper', 'scissors'])
     print "The computer chose: " + player2
     throw(player1, player2)
  except KeyError:
     print "Hey!  I said enter 'rock', 'paper' or 'scissors'!  Try again."
     lets_get_started()

print "Ya wanna play Rock, Paper, Scissors?"
lets_get_started()

Листинг 2: rsp-better.py

Попробуйте! Попробуйте и с неверными данными. Теперь, когда это работает лучше и обрабатывает неверные данные, давайте подумаем о том, как мы можем собирать данные о наших пользователях и записывать их в облако.

Войдите это!

Перед настройкой входа в приложение необходимо включить несколько вещей в своей среде. (Для получения дополнительной информации см. Http://docs.treasuredata.com/articles/python .)

Сначала установите TD-агент

 $ curl -L http://toolbelt.treasuredata.com/sh/install-ubuntu-trusty-td-agent2.sh | sh

Затем обновите /etc/td-agent/td-agent.conf, чтобы включить ваш ключ API

  type tdlog
  apikey 5919/
  auto_create_table
  buffer_type file
  buffer_path /var/log/td-agent/buffer/td
...

Далее перезапустите Treasure Agent:

cookie@monster-ThinkPad-X1:~omnomnom/python$ sudo /etc/init.d/td-agent restart

При перезапуске Treasure Agent вы должны увидеть следующее состояние на консоли:

* Перезапуск td-agent td-agent [OK]

И последнее, но не менее важное: убедитесь, что вы установили fluent-logger в вашу среду Python:

 $ pip install fluent-logger

Как мы уже упоминали ранее, теперь мы хотим собрать данные о

  • выбор нашего пользователя;
  • выбор компьютера;
  • вердикт к игре.

Сбор комментариев к журналу для отправки в Treasure Data через Treasure Agent очень прост. Использование функции события из плавной библиотеки представляет собой одну строку кода:

from fluent import event
event.Event('game_data', {'player': 'Player 1', 'choice': player1 })

Это запишет в нашу базу данных (в таблице с именем ‘game_data’) два столбца (со связанными значениями): ‘player’ (со значением, содержащим строку ‘Player 1’) и ‘choice’ (со значением, содержащим содержимое переменная player1, которая была выбором между «камнем», «бумагой» или «ножницами», которые мы получили в виде необработанного ввода от пользователя).

Давайте обновим нашу программу, чтобы записать оба варианта и вердикт игры в Treasure Data.

Под оператором import random, но перед объявлениями переменных, добавьте эти два оператора import:

from fluent import sender
from fluent import event

Далее, давайте настроим нашу отправительную и локальную базу данных, чтобы она могла отправлять данные в Treasure Data:

sender.setup('td.rsp_db', host='localhost', port=24224)

Наконец, мы добавим наши события регистрации. Во-первых, в нашей функции throw () после того, как мы напечатаем вердикт, давайте запишем его:

  event.Event('game_data', {
     'verdict': verdict
  })

Войти оба выбора игрока. После того, как вы напечатаете выбор игрока 1, зарегистрируйте его:

  event.Event('game_data', {
     'player': 'Player 1',
     'choice': player1
  })

Сделайте то же самое для игрока 2, заменив игрока 1 игроком 2 и переменными соответственно. Когда вы будете готовы, ваш код должен выглядеть как этот файл на github .

Теперь попробуйте запустить ваш файл несколько раз, чтобы заполнить базу данных. Как это работает для вас? Вы столкнулись с какими-либо проблемами? Пожалуйста, оставьте комментарии ниже.

Запрашивающий разум хочет знать

Итак, мы играли в нашу игру несколько тысяч раз и хотим заполнить базу данных. Как мы запрашиваем нашу базу данных?

Один из способов увидеть, что готовится в вашем экземпляре локальной базы данных, — использовать TD Toolbelt непосредственно из bash для запроса и просмотра экземпляра локальной базы данных.

Чтобы просмотреть таблицы в запущенном экземпляре, попробуйте команду td tables (щелкните изображение, чтобы увеличить его):

Вы также можете запустить команду tail, чтобы увидеть самые последние строки вашей локальной базы данных:

$td table:tail rsp_db game_data
{“time”:1429579380,”player”:”Player 2″,”choice”:”paper”}
{“time”:1429579383,”player”:”Player 1″,”choice”:”scissors”}
{“time”:1429579383,”verdict”:”goes to you; the computer loses.”}

Однако в конечном итоге вы захотите запрашивать данные не с устройства, на котором работает ваше приложение, а из облака.

Иногда это помогает очистить буфер Treasure Agent для более быстрой загрузки данных в Treasure Data в облаке. Для этого выполните следующую команду:

$ kill -USR1 cat /var/run/td-agent/td-agent.pid

Теперь у нас должна быть возможность перейти к консоли Treasure Data, чтобы выполнить несколько разных запросов. Для этого войдите на сайт http://www.treasuredata.com и нажмите кнопку «Новый запрос» в правом верхнем углу.

В окне New Query мы должны выбрать базу данных. Попробуйте выполнить несколько простых запросов в консоли, чтобы познакомиться с тем, что в настоящее время находится в вашей таблице:

Select * from game_data

Это покажет вам первые 100 строк в вашей базе данных в порядке убывания, и выберите count (1) из game_data вернет количество строк в вашей таблице.

Конечно, когда вы начнете выполнять аналитику ваших данных, вам захочется сделать больше, чем просто эти простые запросы, поэтому ознакомьтесь с нюансами запросов Hive и Presto . Presto в настоящее время находится в стадии разработки, поэтому, будучи очень мощным, он будет иметь несколько ограничений, которые неправильно переводятся в стандартный SQL.

(Нажмите на картинку для увеличения).

Мы также можем запускать запросы непосредственно из нашего скрипта, если мы подключены к правильному ключу API.

Отсюда вы можете запросить данные в Treasure Data для использования на выбранной вами платформе визуализации, такой как Tableau, Chartio и другие. Мы рассмотрим это в следующем посте. Оставайтесь в курсе!

Узнайте больше на http://docs.treasuredata.com/articles/python