...

суббота, 24 декабря 2016 г.

[Перевод] Фреймворк NancyFX и сервисы в стиле REST

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

Если вдруг вас совсем не интересует фреймворк NancyFX и микросервисы на платформе .NET, создаваемые с его помощью — почитайте про динозавров!

Наш офис ни с чем не перепутаешь — у нас тут установлены надувные динозавры, целый парк видавших виды мониторов, а весь коллектив постоянно гоняет йоркширские чаи. Но, чтобы уделять на такой живительный размандык то время, которого он, безусловно, заслуживает, мы должны быстро и эффективно решать наши основные задачи – в частности, поддерживать сервис, при помощи которого наши клиенты могут бронировать гостиничные номера.

Чтобы это получалось еще лучше, мы постепенно переделали наш сегмент базы кода под микросервисную архитектуру. Первым делом мы написали API Reservations, выделив весь функционал, связанный с созданием и извлечением записей о бронировании в отдельный домен с независимыми системами версионирования, релизов и обслуживания. Так нам удалось без труда поддерживать новые кроссплатформенные фронтенды – например, мобильную версию и форму бронирования на основе Node.js

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

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

NancyFx – потрясающий легкий веб-фреймворк для .NET. Если вы ориентируетесь во фреймворках для других языков, например, Sinatra и Express, то уже вполне представляете, что от него ожидать. С другой стороны, если знакомы лишь с такими .NET-глыбами как Microsoft MVC и WCF, то, вполне возможно, вас ждет приятный сюрприз.

Вместо того, чтобы распевать дифирамбы Nancy (я это могу делать часами), лучше продемонстрирую вам, насколько проще пареной репы написать на Nancy простейшую оконечную точку в стиле REST менее чем за 15 минут.

Шаг 1: Создаем консольное приложение на C#

Разумеется, это можно сделать и на другом языке для платформы .NET. Даже на VB.

Шаг 2: Импортируем Nancy

Nancy предоставляется в виде пакетов Nuget, так что рекомендую воспользоваться менеджером пакетов Visual Studio – самым удобным инструментом для импорта двоичных файлов в проект и ссылки на них. В данном случае нам понадобится пакет Nancy.Hosting.Self, зависящий от основного пакета Nancy.

Шаг 3: Создаем хост Nancy

В методе Main (или эквивалентной входной точке программы) напишите:

using (var host = new NancyHost(new Uri("http://localhost:1234"))
{
    Console.ReadKey();
}

Вы уже создали консольное приложение, которое слушает HTTP на порте 1234. На самом деле, нам нравится так делать, это простая реализация обратных прокси, передающих внешние HTTP-запросы управляемому процессу. Однако, Nancy поддерживает и OWIN, традиционный IIS-хостинг.

Шаг 4: Создаем маршрут к ресурсу

Создаем наш первый маршрут, наследуя класс Module из Nancy. Напишите вот это в файле с новым проектом:

class Dinosaur
{
    public string Name { get; set; }
    public int HeightInFeet { get; set; }
    public string Status { get; set; }
}

class DinosaurModule : NancyModule
{
    private static Dinosaur dinosaur = new Dinosaur()
    {
        Name = "Kierkegaard",
        HeightInFeet = 0,
        Status = "Deflated"
    };

    public DinosaurModule()
    {
        Get["/dinosaur"] = parameters => dinosaur;
    }
}


При запуске хоста Nancy просматривает вашу сборку и ищет в ней классы, наследующие NancyModule. Они будут инстанцироваться всякий раз при поступлении запроса, обеспечивать маршрутизацию и действия. В данном случае мы создаем простой маршрут GET в конструкторе модуля и пользуемся лямбда-выражением, при помощи которого возвращаем определенный нами объект модели. Если вызвать localhost:1234/dinosaur без заголовка с типом содержимого, то модель динозавра придет нам в формате JSON. Запустите приложение, попробуйте.

Шаг 5: Добавляем операцию записи

До сих пор наш ресурс был только для чтения. Добавьте в конструкторе DinosaurModule такой код:

Post["/dinosaur"] = parameters =>
{
    var model = this.Bind<Dinosaur>();
    dinosaur = model;
    return model;
};

Привязка принимает тело HTTP-запроса и пробует ассоциировать его с заданным типом модели. Попытайтесь послать следующий код на localhost:1234/dinosaur, тип содержимого — application/json:
{
    "name": "Kierkegaard",
    "heightInFeet": 6,
    "status": "Inflated"
}


Тело запроса следует привязать к классу Dinosaur и присвоить нашему статическому члену Dinosaur. Как и в случае с конечной точкой Get, мы возвращаем модель, после чего Nancy сериализует модель JSON. В Nancy есть такие возможности как обсуждение содержимого и рендеринг представления, но в данном демонстрационном примере нам вполне подойдет поведение, задаваемое по умолчанию.

Шаг 6: Создаем и возвращаем индексированные ресурсы

Как правило, когда мы пишем REST API, нам требуется по несколько от каждого ресурса. Давайте немного модифицируем класс:

public class DinosaurModule : NancyModule
{
    private static List<Dinosaur> dinosaurs = new List<Dinosaur>()
    {
        new Dinosaur() {
           Name = "Kierkegaard",
           HeightInFeet = 6,
           Status = "Inflated"
        }
    };

    public DinosaurModule()
    {
        Get["/dinosaurs/{id}"] = parameters => dinosaurs[parameters.id - 1];
        Post["/dinosaurs"] = parameters =>
        {
            var model = this.Bind<Dinosaur>();
            dinosaurs.Add(model);
            return dinosaurs.Count.ToString();
        };
    }
}

Теперь маршрут - /dinosaurs. Объект parameters в лямбда-выражении – это, в сущности, динамический тип, комбинирующий значения из маршрута, строки запроса и тела запроса. Определяя параметр {id} в рамках маршрута, можно захватывать его, а потом с его помощью извлекать нужный нам ресурс.

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

Шаг 7: Ваш ход

В финале нашей весьма обзорной экскурсии у нас получилась такая спартанская оконечная REST-точка. А что дальше? Естественно, мы хотим держать наши ресурсы в каком-то долговременном хранилище данных, а не в памяти, но что насчет валидации, обработки ошибок, безопасности?

При всей легкости и простоте Nancy прямо «из коробки» решает и многие подобные вопросы, а также предоставляет другие возможности, которые вы сможете с легкостью внедрить в проект.
Итак, общее представление о Nancy вы составили – а теперь почитайте документацию.

Комментарии (0)

    Let's block ads! (Why?)

    Выгорание фрилансера на Upwork. Причины, инструменты, решения

    Релиз Python 3.6 — да, теперь он с нами

    пятница, 23 декабря 2016 г.

    [Перевод] Пять мощных паттернов монетизации F2P, использующих в дизайне UX поведенческую экономику

    [recovery mode] Пятничный пост: opensource CRM уходящего года

    Распределение Пуассона и футбольные ставки




    Если объединить статистические данные спортивных соревнований с распределением Пуассона, то можно рассчитать вероятное количество мячей, которые будут забиты во время футбольной игры. На этом основании можно понять откуда берутся букмекерские ставки, а также научиться самостоятельно их рассчитывать с помощью R.


    В конце XIX в. русский экономист и статистик польского происхождения Владислав Борткевич, проанализировав данные в 14 корпусах прусской армии за 20 лет, придумал способ предсказывать случаи гибели солдат от удара копытом лошади. Для этого он одним из первых использовал на практике распределение Пуассона. Результаты его расчетов показаны в таблице.


    Смертность от удара лошади Согласно формуле Пуассона Наблюдения
    0 108.67 109
    1 66.29 65
    2 20.22 22
    3 4.11 3
    4 0.63 1
    5 0.08 0
    6 0.01 0

    Как видим теоретико-вероятностные вычисления отлично сочетаются с реальными данными. Можно ли применить этот способ в ставках на спорт, чтобы развлечься и заработать?


    Формула Пуассона


    В классическом учебнике по теории вероятностей Б В. Гнеденко дается такое определение теоремы Пуассона.





    Если же говорить простым языком, то на основе этой формулы можно рассчитать распределение вероятностей для событий, которые:


    • происходят за единицу времени или на единицу площади;
    • дискретны, их можно пронумеровать;
    • независимы друг от друга;
    • не имеют верхней границы, по крайней мере — теоретической;

    Можно привести уйму примеров из повседневной жизни: количество пострадавших от удара молнии, от ДТП, количество рекламных звонков и сообщений, число поломок лифта за год, изюминок в пасхальном куличе и т. д. Для нас же интерес представляют примеры из спорта.


    Футбольная статистика


    Оказывается, количество забитых мячей в футбольном матче очень хорошо вписывается в Пуассоново распределение. Так, на диаграмме слева мы видим число голов, забитых каждой командой в каждом из 380 матчей чемпионата Испании 2008–2009 годов. На диаграмме справа подсчитаны теоретические данные модели.





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


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


    Англия — Премьер-лига 1 x 2
    Манчестер Юнайтед — Сандерленд 1,25 6,80 15,00
    Челси — Борнмут 1,39 5,10 10,50
    Халл — Манчестер Сити 10,50 5,80 1,35

    1 — победа первой команды
    x — ничья
    2 — победа другой команды.


    Достаточно мельком взглянуть на турнирную таблицу и станет понятно, почему так высоки ставки и возможный выигрыш в случае победы Сандерленда над Манчестер Юнайтед. За каждый фунт стерлингов в этом случае можно заработать 15 фунтов стерлингов, с фантастическими 1400% прибыли. В случае же победы команды Манчестер Юнайтед выигрыш будет всего 1,25 фунтов стерлингов, прибыль составит всего 25%.


    Попробуем теперь сами рассчитать ставки на игру Манчестер Юнайтед против Манчестер Сити, которая должна состояться 26-го февраля 2017 г. Несмотря на то, что у двух клубов названия похожи, МС играет на своем поле, а МЮ — в гостях.


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


    µMU — Ожидаемое количество забитых мячей для Манчестер Юнайтед
    µMC — Ожидаемое количество забитых мячей для Манчестер Сити


    Тогда


    • µMU = нападение МЮ ✕ оборона МС ✕ среднее количество забитых на выездных матчах.
    • µMC = нападение МС ✕ оборона МЮ ✕ среднее количество забитых голов на своем поле.

    За весь сезон 2015/2016 было 380 футбольных игр, в которых команды у себя дома забили 567 мяча (1.49 за игру), а в гостях — 459 (1.20 за игру).


    (5:563)$ echo 'scale=5;567/380;459/380' | bc -q
    1.49210
    1.20789
    

    Далее, считаем коэффициенты нападения МЮ, нападения МC, оборона МЮ и обороны МС.





    На выездных матчах Манчестер Юнайтед забивал в среднем 1.15 мячей за игру, а пропускал — 1.36.


    (5:552)$ echo 'scale=5;22/19;26/19' | bc -q
    1.15789
    1.36842
    

    У себя дома Манчестер Сити забивал в среднем 2.47 мячей за игру, а пропускал — 1.10.


    (5:553)$ echo 'scale=5;47/19;21/19' | bc -q
    2.47368
    1.10526
    

    Теперь те же самые значения мы взвешиваем относительно общих средних значений. Относительное среднее нападения МЮ на чужом поле равно 0.958, а относительное среднее обороны МС на своем поле — 0.915.


    (5:554)$ echo 'scale=5;22/19/1.20789;21/19/1.20789' | bc -q
    .95860
    .91503
    

    Относительное среднее обороны МЮ на чужом поле равно 0.917, а относительное среднее нападения МС на своем поле — 1.657.


    (5:555)$ echo 'scale=5;26/19/1.49210;47/19/1.49210' | bc -q
    .91711
    1.65785
    

    И наконец, перемножая все промежуточные средние значения, находим µ.


    µMU = 1.06
    µMC = 2.27


    (5:556)$ echo 'scale=5;.95860*.91503*1.20789;1.65785*.91711*1.49210' |bc -q
    1.05948
    2.26863
    

    Голы по Пуассону


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


    > dpois(x=(0:5), lambda=2.26863)
    [1] 0.10345381 0.23469843 0.26622195 0.20131970 0.11417998 0.05180642
    > dpois(x=(0:5), lambda=1.05948)
    [1] 0.346636014 0.367253924 0.194549094 0.068706958 0.018198412 0.003856171
    

    Итак, вероятности распределены следующим образом.


    Голы 0 1 2 3 4 5
    МЮ 34.663% 36.725% 19.454% 6.870% 1.819% 0.385%
    МС 10.345% 23.469% 26.622% 20.131% 11.417% 5.180%

    Вероятность того, что Манчестер Юнайтед не забьет ни одного гола составляет 34.663%, то же самое для Манчестер Сити — 10.345%, вероятность нулевого исхода встречи равна их произведению и составляет 3.586%. Матрица всех результатов от 0:0 до 5:5.


    > a=dpois(x=(0:5), lambda=1.05948)
    > b=dpois(x=(0:5), lambda=2.26863)
    > A=a%*%t(b)
    > A
                 [,1]         [,2]        [,3]         [,4]         [,5]         [,6]
    [1,] 0.0358608180 0.0813549276 0.092282115 0.0697846579 0.0395788921 0.0179579724
    [2,] 0.0379938195 0.0861939186 0.097771055 0.0739354494 0.0419330446 0.0190261126
    [3,] 0.0201268459 0.0456603665 0.051793239 0.0391665649 0.0222136111 0.0100788929
    [4,] 0.0071079969 0.0161254150 0.018291300 0.0138320641 0.0078449589 0.0035594618
    [5,] 0.0018826951 0.0042711387 0.004844817 0.0036636988 0.0020778943 0.0009427947
    [6,] 0.0003989356 0.0009050372 0.001026597 0.0007763231 0.0004402975 0.0001997744
    

    Попробуем теперь рассчитать вероятность победы каждой из сторон, вероятность ничейного исхода и наконец определимся со ставками. Начнем с ничейного результата. Перемножаем векторы событий для МЮ и МС, и считаем сумму диагональной матрицы. Ставка 1 к 5.264.


    > sum(diag(A))
    [1] 0.1899577
    > 1/sum(diag(A))
    [1] 5.26433
    

    Шансы победы МС равны сумме всевозможных 1:0, 2:0, … 5:0, 2:1, 3:1, … и т. д. до 5:4. Ставка равна 1.619.


    sum(A[1,2:6])+sum(A[2,3:6])+sum(A[3,4:6])+sum(A[4,5:6])+A[5,6]
    [1] 0.6174305
    1/(sum(A[1,2:6])+sum(A[2,3:6])+sum(A[3,4:6])+sum(A[4,5:6])+A[5,6])
    1.619615
    

    Шансы победы МЮ поменьше, соответственно побольше будет ставка и денежный выигрыш — 1 к 5.191.


    > 1 - (sum(A[1,2:6])+sum(A[2,3:6])+sum(A[3,4:6])+sum(A[4,5:6])+A[5,6] + sum(diag(A)))
    [1] 0.1926118
    > 1/(1 - (sum(A[1,2:6])+sum(A[2,3:6])+sum(A[3,4:6])+sum(A[4,5:6])+A[5,6] + sum(diag(A))))
    [1] 5.19179
    

    Ставки сделаны!


    Ставки на игру 1 x 2
    Манчестер Сити — Манчестер Юнайтед 1.620 5.264 5.192

    Конечно, модель Пуассона довольно проста и не учитывает множество факторов и обстоятельств: новый игрок, новый тренер, статус матча, обстоятельства клуба и т. д. Тем не менее Elihu Feustel умудряется на ставках зарабатывать миллионы, используя математические алгоритмы.


    Использованные материалы


    Комментарии (0)

      Let's block ads! (Why?)

      [Из песочницы] Исследование датасета с IMDB

      [Из песочницы] Личный опыт: как мы выбирали DLP-систему

      [Перевод] 19 неожиданных находок в документации Node.js

      [Из песочницы] Аналог .Net Entity Framework в Delphi посредством RTTI. Часть первая, вступительная

      C++ Russia 2017

      Пятничный формат: Удачно выйти в отпуск или поработать еще немного

      Трудоголиков становится все больше, а предприниматели, программисты, дизайнеры и маркетологи часто объясняют свои переработки тем, что им просто нравится своя работа.

      По результатам исследования, проведенного в Стэнфордском университете, программисты, которые проводят в офисе на 20 часов в неделю больше нормы (то есть 60 часов вместо стандартных 40), выполняют свою работу менее качественно. Таким работникам чаще нужен отдых, чтобы их производительность не страдала.

      Мы в 1cloud рассматриваем самые разные темы, связанные с ИТ. Сегодня мы решили немного поговорить о культуре работы и отдыха, рассмотрели примеры отпускных поощрений некоторых ИТ-компаний и общую ситуацию с модой на трудоголизм.


      / Flickr / Nick Kenrick / CC

      Можно предположить, что самые классные бонусы, связанные с отпускными путешествиями, предлагают своим сотрудникам туристические агентства или авиалинии. Но на стыке travel'а и технологий находится самый известный пример отпускной «плюшки» — 2 тысячи долларов, которые Airbnb выделяет своим сотрудникам на оплату жилья в любой точке мира через собственный сервис.

      По такому же пути решили пойти в компании Rocketmiles (онлайн-платформа, которая дает возможность получить мили за проживание в отеле). Каждому сотруднику, уходящему в отпуск, компания выделяет тысячу долларов, которые можно потратить на сайте работодателя. А в Epic Systems работникам начисляют мили и баллы, которые можно потратить на оплату полетов и проживания в отелях.

      Есть и другие примеры щедрости компаний. Сотрудники американской ИТ-компании Loadspring уже после двух лет работы могут получить дополнительный отпуск и до 6 тысяч долларов на оплату путешествий за пределами США.

      Кроме того, компании часто увеличивают размер отпуска в зависимости от стажа работы: например, в Google отпуск увеличивается с 15 дней при трудоустройстве до 25 дней после пяти лет работы. В Intel оплачиваемый отпуск в размере 4 недель (подряд) можно взять после 4-х лет работы, а раз в 7 лет можно получить целых 8 недель.

      Безлимитный отпуск


      Такую систему выбирают все больше и больше компаний: например, Twitter, Pinterest, Zynga, Automattic. А самыми первыми ее ввели в Netflix еще в 2004 году. Точнее, они лишь открыто отказались от системы расчета отпусков и строгого контроля.

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

      Первоначально у компании были опасения относительно потенциальных злоупотреблений и возможной потери контроля над рабочей обстановкой, но как правильно написано в корпоративной политике компании Netflix: «у нас также отсутствует дресс-код, однако никто не приходит на работу голый».

      Сотрудники понимают, что от них ожидают выполнения рабочих обязанностей. В этом и заключается основная проблема такого бонуса — культура трудоголизма просто не дает решиться на полноценный отпуск. Кроме того, компании часто пишут в правилах, что длина отпуска должна быть приемлемой. Но кто определяет эту приемлемость? Особенно если в компании нет сезонного затишья и весь год горят сроки и проекты, то времени даже на мысли об отпуске может не быть.

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

      Отдыхать-то некогда


      Жесткая конкуренция, а в сфере IT она еще выше за счет большого количества квалифицированных специалистов, которые могут работать из любой точки планеты, не дает расслабиться. Но не только в крупных компаниях принято перерабатывать — работая в маленьком стартапе, вы с большой доли вероятности будете перегружены дополнительными функциями и должностными обязанностями.

      Как тут уедешь, когда даже не на кого переложить свою работу? Вот и получается, что, даже если и удастся выбраться в отпуск, скорее всего, придется работать дистанционно.

      Конечно, все зависит от компании. Где-то принято брать по 2-3 дня в течение года, где-то, наоборот, частые отгулы считаются неуместными. Но главное, что очень мало сотрудников решаются отпроситься у начальника в длительный отпуск.

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

      А зачем тратить по 4 часа в день на дорогу, когда можно выспаться на рабочем месте? К тому же дневной сон тоже не возбраняется и для перезагрузки мозгов можно вздремнуть минут 30.

      Российские компании еще не дошли до таких крайностей, хотя небольшие переработки тоже воспринимаются как что-то само собой разумеющееся. Хотя все познается в сравнении: из-за того, что в Китае нет нормированного рабочего дня, в среднем житель Гонконга работает по 2606 часов в год, что почти на тысячу часов больше, чем среднестатистический москвич (1674 часов).

      Важное отличие в отпускной системе — в США оплачиваемый отпуск не является обязательным на законодательном уровне и у 25% американцев его просто нет. С этой точки зрения ситуация на ИТ-рынке выглядит не так уже плохо. Россия же находится на первом месте по суммарному количеству государственных праздников (12 дней) и отпускных дней (28).

      Если обратиться к статистике по отпускам, то на 2016 год 53% американцев не уезжало в отпуск длиной больше 7 дней за последние 12 месяцев, а 37% никуда не выезжали уже два года подряд. В пересчете на дни, американцы не потратили 658 миллионов оплачиваемых отпускных дней. В России в этом году продолжительность отпусков в летний период сократилась на 24%, а 48% опрошенных намеревались полностью отказаться от отпуска в этом году.

      P.S. Ну а мы продолжаем работать. Наш сегодняшний материал — Личный опыт: Как мы автоматизировали работу с DNS-записями в хостинг-панели.

      Комментарии (0)

        Let's block ads! (Why?)

        AppCode 2016.3: поддержка Swift 3, новые настройки форматирования, улучшения быстродействия и многое другое

        Привет, Хабр!

        Совсем недавно вышел AppCode 2016.3, и в этом посте мы расскажем о самых интересных изменениях в нем.



        Swift


        Поддержка Swift 3


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

        Create from usage


        В каждом новом обновлении мы стараемся расширить возможности кодогенерации для Swift. Это и Live Templates, в том числе позволяющие «обернуть» выделенный участок кода, и рефакторинг Introduce Variable, и Override/Implement (^O/^I), с помощью которого можно сгенерировать определения сразу для нескольких методов.

        В этом релизе мы добавили возможность создавать переменные, функции, методы и даже свойства классов из их использований. Особенно это удобно, если нужно что-то быстро cпрототипировать. Пусть метода ещё нет, напишем его, передадим нужные аргументы, вызовем ⌥⏎ — и все, остается лишь немного исправить автоматически сгенерированную сигнатуру функции, если это необходимо:

        Как видно на гифке, используя тот же принцип можно создавать и другие сущности в коде. Аналогичную возможность для генерации типов (классов, структур и т. п.) мы планируем добавить для Swift чуть позже. А вот в Objective-C/C/C++ все эти возможности уже давно есть, и пользоваться ими можно и нужно прямо сейчас.

        Форматирование кода


        Для Objective-C/C/C++ в AppCode есть масса настроек форматирования:

        Применить их можно, вызвав ⌘⌥L на выделенном участке кода (а если код не выделен, будет отформатирован файл целиком). Базовые возможности для Swift были реализованы еще в версии 3.1, при этом многих настроек форматирования, специфичных для языка, среди них не было. В этом релизе мы решили их добавить.

        Теперь в AppCode можно настраивать различные правила переноса для:

        • Параметров замыканий
        • Простых замыканий в различных случаях их использования в коде:

        • Параметров в объявлениях методов и функций
        • Аргументов методов и функций, используемых в коде
        • Последовательных вызовов методов:

        • Нескольких условных конструкций на одной и той же строке

        Также добавлен блок для пробелов до и после двоеточий в спецификациях типов переменных, словарей и парах «ключ: значение» в самих словарях:

        Быстродействие


        Мы улучшили быстродействие AppCode при работе со Swift по нескольким основным направлениям.

        Первое — вывод типов. От него в AppCode зависит и скорость подсветки кода, и скорость автодополнения, и многое другое. В итоге удалось даже для сложных конструкций кода его существенно ускорить.

        Второе — скорость автодополнения. Здесь мы основательно поработали над кэшированием списка вариантов, что позволило сделать его значительно более быстрым.

        Также удалось исправить несколько проблем в интеграции с SourceKit, которые отражались на скорости показа ошибок, предупреждений и исправлений (fix-it).

        UI-тесты


        Теперь в AppCode можно запускать (^⌥R) и отлаживать (^⌥D) UI-тесты. Упавшие тесты можно отфильтровать от пройденных и после исправлений перезапустить только их:

        Результаты запуска тестов можно отсортировать по продолжительности (или по имени):

        Все они сохраняются во встроенной истории, и позже их можно просмотреть прямо в IDE:

        Семантическая подсветка


        Как и во многих других продуктах JetBrains, в AppCode появилась возможность подсветки параметров функций и переменных уникальными цветами. Включить ее можно для Swift/Objective-C/C/C++ в настройках Editor → Colors & Fonts → Language Defaults → Semantic highlighting:

        C/C++


        По традиции, улучшения поддержки C/C++, реализованные командой CLion, доступны и в AppCode. Про них можно прочитать в этом посте в разделах Поддержка C и Поддержка С++, соответственно. Кстати, различные платформенные изменения (такие как улучшения в поддержке контроля версий, San Francisco в качестве дефолтного шрифта в меню и другие), описанные в этом посте, также доступны в AppCode.

        Демо


        Небольшое демо (на английском) с демонстрацией новых возможностей от нашего девелопер-адвоката Фила Нэша:

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

        Комментарии (0)

          Let's block ads! (Why?)

          Истории о новогодних багах

          Верите ли вы в волшебство? С логической точки зрения — конечно, нет! Программисты, разработчики — серьезные люди, с хорошим образованием и реалистичным взглядом на мир. Может вы и в детстве не любили сказки? Нет, я не буду больше отвечать за вас. Просто попрошу налить кружечку чая, почистить мандарин, взглянуть на снежинки за окном и только после этого начать читать эту Историю.

          Перед вами рассказ о Злобном Баге. О том, как он неоднократно пытался испортить новогодние праздники. Часто ему удавалось воплотить свои коварные замыслы, но, к счастью, в каждой Сказке «злу» противостоит настоящее «добро».

          Picture 3


          Елочка-вирус


          17 декабря 1987 года студент немецкого университета Клаустал-Зеллерфилд, будучи еще совсем молодым программистом, решил оригинально поздравить своих друзей. Он отправил всем близким и дорогим рождественскую ель! Конечно, он не срубил ее в лесу и даже не купил в магазине. Не забывайте, наш герой — программист, поэтому он написал программу на языке REXX для VM/CMS, которая после запуска выводила на экран милую елочку и теплые поздравления.

          Рисунок 1 - Программа Christmas Tree - елочка вирус


          Рисунок 1 — Программа Christmas Tree — елочка вирус

          С благими намерениями и искренним желанием сделать добро писал код наш герой. Но Злобный Баг вклинился в процесс, произошла перегрузка сети и самовоспроизводящаяся программа Christmas на два дня парализовала работу частной почты IBM Vnet (цепочка: университетская сеть — EARN — BitNet — IBM-Vnet) по всему миру. Возникли сомнения: а не является ли герой — антигероем, а трогательное поздравление — вирусом? Доказать злой умысел автора программы Christmas Tree не удалось. Но без влияния Злобного Бага здесь точно не обошлось.

          Аттракцион невиданной щедрости


          Рождество и Новый год — праздники, на которые принято дарить подарки. Красивые коробки под ёлкой или милые сувениры в рождественских носках, подвешенных у камина, — так выглядят традиционные новогодние подарки. Но особенно приятны сюрпризы.

          Amazon — один из первых интернет-сервисов, на котором ежедневно продаются и покупаются десятки тысяч разнообразных товаров. Идеальное место для выбора подарков! Именно этим и занимались пользователи 12 декабря 2014 года. Особый ажиотаж вызвала потрясающая цена на тысячи товаров — всего 1 пенни (источник). Благодаря сервис за великолепный рождественский подарок, люди с особым энтузиазмом занялись покупками. А Злобный Баг ухмылялся в сторонке, ожидая реакции продавцов, еще не знающих о том, что они понесли огромные убытки.

          Ошибка закралась в программное обеспечение RepricerExpress, отвечающее за синхронизацию цен в онлайн-магазинах. С его помощью продавцам проще конкурировать на рынке, оперативно реагируя на изменение цен аналогичных товаров.

          Что сделал Злобный Баг? Он проник в RepricerExpress еще на этапе проектирования и тестирования, но не заявлял о себе до того момента, пока… Один из поставщиков, закрутившись в предпраздничной суете, случайно установил единую цену на весь свой ассортимент — 1 пенни. Программа приняла это значение за минимальное и снизила цену на товары других продавцов.

          Причина такого поведения объясняется тем, что в ходе разработки пользовательского интерфейса не была предусмотрена возможность установки собственной минимальной цены на товар. Кроме того, через определенные временные промежутки происходила автозамена цены. При последующем обновлении баг был исправлен.

          Рисунок 2 - Правильный интерфейс системы (появился столбец Your Minimum Price)


          Рисунок 2 — Правильный интерфейс системы (появился столбец Your Minimum Price)

          День, когда произошла данная ошибка, продавцы Amazon запомнят надолго. Они потеряли тысячи долларов, многие оказались на грани банкротства (источник). Если бы не оперативные меры Amazon, сумевшего аннулировать большую часть заказов, то репутация крупнейшего интернет-магазина была бы совершенно испорчена.

          Разработчики RepricerExpress извинились за сбой ПО, опубликовав заявление в своем официальном блоге.

          Apple против Нового года


          Помните фильм "Гринч — похититель Рождества"? Видимо, Злобный баг вдохновился его сюжетом, решив нанести удар «яблочным» девайсам. В феврале 2016 года владельцы техники Apple обнаружили занятный баг. В социальных сетях зародилась легенда о том, что если установить дату 1 января 1970 года, а затем выполнить перезагрузку устройства, то произойдет полный крах системы, а вместо смартфона или планшета у вас в руках окажется кирпич с эмблемой «яблочко». При этом возможности откатить действие нет. Были сведения о присутствии данной ошибки на устройствах с 64-битным процессором: Apple A7, A8, A8X, A9 и A9X: iPhone 5S и последующие, iPad Air и iPad Mini 2 и новее, а также 6-е поколение iPod Touch. Версия операционной системы значения не имела.

          Picture 2

          Нашлись ли желающие опытным путем проверить наличие бага? Несомненно! По всему миру прокатилась волна убийств гаджетов Apple. К счастью, умельцы нашли способ вернуть работоспособность «кирпичам». В Apple официальную причину ошибки не озвучили, но заявили о возможности такого бага, при ручной установке на iOS-устройстве дату в мае 1970 года или ранее.

          Пользователи провели собственное расследование. В результате сформировалась следующая версия: к ошибке могла привести переменная с отрицательным значением, хранящая в себе время в формате UNIX. Почему это могло произойти?

          Вариант 1. По причине того, что время представлено в UNIX-формате, начало отсчета ведется с 1 января 1970 года, т.е. является нулем. При изменении часового пояса, переменная может принять значение меньше нуля.

          Вариант 2. Баг характерен для 64-х битных устройств, поэтому возможно, в первую очередь вычисляется 32-х битная метка времени, затем происходит смещение по часовому поясу, метка конвертируется в размер указателя, по этой причине старшие биты заполняются неверно и… Добро пожаловать в XXII век!

          Сон от IPhone


          Продолжительный сон, не прерываемый звуком будильника, — разве это не мечта большинства из нас? iPhone — не Газпром, но исполняет мечты своих пользователей! Все те, кто хотел бодро начать новый 2013 год и поставил будильник на 1 января, благополучно проспали. Злобный баг явно замыслил ввести огромное количество пользователей в режим «спящей царевны», т.к. вплоть до 3 января будильник на iPhone не работал.

          Picture 7

          Apple снова решил отмолчаться. Но версия о причинах возникновения ошибки все равно распространилась. Для отображения года используется стандарт ISO week date, он широко применяется в финансовых организациях для удобства формирования отчетного (финансового) года. Его особенность состоит в том, что новый год считается новым только с той недели, которая содержит первый четверг года. Календарь в стандарте ISO week date содержит 52 или 53 недели (364 или 371 день). Таким образом, iPhone жил по старому году, а новый 2013 наступил только 7 января — с новой полной недели года.

          Была и альтернативная версия, в которой в качестве Злобного бага выступал сам Стив Джобс. Якобы, основатель Apple любил спать, вот и придумал такую фичу. Конечно, это шутка. А вот последствия у такого, казалось бы, несерьезного бага оказались более чем неприятными: люди проспали работу, потеряли деньги, опоздали на важные встречи (Источник).

          Полет отменяется


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

          12 декабря 2014 года в британском центре УВД Национальной службы воздушного движения Великобритании (NATS) произошел программный сбой. Работа части аэропортов, в том числе таких загруженных гигантов, как Хитроу, Гатвик, Станстед, Бирмингем, Кардифф и Глазго была остановлена. Усугубило проблему и время, которое Злобный баг выбрал для атаки — пятница, вторая половина дня, преддверие рождественских праздников.

          Сбой длился чуть более получаса — 36 минут, но его последствия свидетельствуют о крайне высокой цене ошибки. Злобный баг постарался на славу:

          • 92 рейса отменено
          • 170 рейсов задержано
          • 10 воздушных суден были вынуждены уйти на запасные аэродромы
          • 125000 пассажирам были причинены неудобства
          • 623 млн фунтов стерлингов потеряла британская казна

          Подобная ситуация не могла остаться без внимания. Было проведено расследование. Управление гражданской авиации (CAA) и NATS в заключительном отчете описывают баг в программном обеспечении System Flight Server (SFS). Этот сервер отвечает за то, чтобы в систему управления NATS в режиме реального времени поступали данные на контроллер рабочих станций. В системе существует два одинаковых SFS — работающий и запасной. Оба вычисляют одни и те же данные. При отключении основного SFS, в работу вступает запасной. Система работала при аппаратных сбоях, но по каким-то причинам ни на одном из серверов не была предусмотрена защита от программных исключений.

          Максимальное количество одновременно функционирующих рабочих станций (мест управления полетами и наблюдения за ними) — 193. Теоретически. Фактически же в коде SFS прописано совершенно другое значение — 151. Поэтому, когда произошла попытка одновременного подключения 153 рабочих станций, началась перезагрузка и последующее «падение» системы. Позже выяснилось, что «скрытая неисправность программного обеспечения» была допущена еще в 1990 году. Удивительно, что она не проявилась раньше.

          Проблема 2000 и 2038


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

          Чем же аргументировался страх перед Терминаторами? Логикой! Первые компьютеры были медлительны, поэтому, чтобы не тратить столь ценную производительность на пустяки, разработчики приняли решение использовать два знака представления кода в датах. Например, 23 марта 1991 года выглядело как 23.03.91. Визуально такое обозначение не «режет глаз», данный вариант записи даты кажется абсолютно привычным. Но с точки зрения компьютера все не так просто: 2000 год и 1900 получают одинаковое обозначение: 00. Таким образом, при наступлении 2000 года внутренние часы компьютера переведутся на 1900 год.

          Последствия подобного сбоя представлялись крайне ужасными: выход из строя программ, самопроизвольный запуск ракет, обрушение финансового рынка. А самые страшные события должны были произойти в России, как в стране, наименее готовой к новому летоисчислению.

          Но совсем скоро наступит уже 2017 год, а значит, Конец света не произошел.

          Впрочем, некоторые сбои при смене тысячелетия все же произошли:

          • Пострадали компьютерные сети British Telecom. Их работала была парализована, а для восстановления потребовалось проанализировать около миллиона строк кода. Обошлось это British Telecom недешево — около $0.5 млрд.
          • В Испании были зафиксированы происшествия на 9 ядерных реакторах. К счастью, обошлось без последствий.
          • В Монголии «Проблема 2000» затронула систему начала движения поездок и билетные кассы.

          Некоторые баги были весьма забавны:
          • Сроки заключения в одной из испанских тюрем выросли/сократились на 100 лет
          • В некоторых магазинах Греции люди при покупке получили чек, датированный 1900 годом
          • В южнокорейском госпитале компьютерная программа «Контроль за пациентами» объявила годовалого ребенка 99-летним стариком
          • А жители небольшого города в США получили просроченные на 100 лет счета за пользование электроэнергией

          Проблема 2000 — это яркий пример того, как СМИ способны воздействовать на человечество. Следующей волны паники по аналогичному поводу стоит ожидать в 2038 году. 19 января 2038 года в 03:14:07 по Гринвичу компьютеры и другие устройства с 32-битной системой не смогут больше верно отсчитывать время. Многие вычислительные устройства отсчитывают системное время с 1 января 1970 года в секундах, используя 32-битное значение, а секунда хранятся в виде signed int (32-битного целого со знаком). В 2038 году наступит 2 147 483 648-я секунда, которую просто не будет возможности записать системой, и тогда счётчик примет отрицательное значение.

          Как предотвратить системную ошибку? Заменить все 32-битные процессоры на 64-битные.

          Как помочь Добру?


          По традиции, Добро побеждает Зло, но борьба не прекращается ни на миг. Можно ли истребить всех Злобных багов? Скорее всего, нет, но вполне реально сделать так, чтобы их армия понесла значительный урон. Для этого программисты, сражающиеся за Добро, т.е. качественный код, должны ответственно подойти к выбору вспомогательных средств. Вооружайтесь статическим анализатором PVS-Studio! А также вы можете посмотреть хоррор-короткометражку о том, как Единорог PVS-Studio спасает Пингвина Linux от Злобного бага.

          Вдохновились? Тогда предлагаем всем разработчикам помочь Добру! Команда PVS-Studio уже сделала значительный шаг в этом направлении, предложив бесплатную версию анализатора.

          Picture 6

          Уважаемые программисты, желаем вам удачи в Новом году и пусть ваши истории о Злобных багах всегда заканчиваются победой Добра!

          Комментарии (0)

            Let's block ads! (Why?)

            Финансовый Telegram-бот за 30 минут с Market Data API

            Обычно в статьях про финтех пишут о том, как работают биржи, которые обрабатывают огромные объемы данных на огромных скоростях, о том, как гениальные трейдеры и кванты используют отточенные алгоритмы, чтобы зарабатывать (или терять, бывает всякое) миллиарды долларов, или о работе блокчейна, обеспеченной сложными математическими выкладками. Все это создает впечатление, будто уровень входа в финтех-разработку запредельно высок. И отчасти оно правдиво — требования к разработчикам высоконагруженных финансовых приложений строги и специфичны.

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



            Из обзоров современных технологий взаимодействия с пользователями видно, как быстро набирают популярность всевозможные боты и помощники, понимающие запросы на естественном языке. Поддержим этот тренд и создадим простого Telegram-бота, который сможет что-то рассказать пользователю о рынке по запросу.

            Доступ к данным


            Начнем с простой ситуации: приложение будет использовать текущие и исторические данные о торгах, а не отправлять на биржу собственные заявки. Эти данные (т. н. market data, или биржевую информацию) можно получать у ряда компаний за относительно небольшую плату или вообще бесплатно. С отправкой заявок все заметно сложнее (как минимум — дороже), и мы рассмотрим этот процесс подробнее в следующих статьях.

            Какие существуют технологии для получения биржевых данных? Список их не слишком велик: это FIX-протокол (реализации могут немного различаться от поставщика к поставщику), FAST, ITCH и несколько вариантов бинарных и HTTP API (к примеру, CQG, EXANTE или MOEX). Впрочем, универсализация здесь не так принципиальна: набор предоставляемых данных может сильно различаться, и в любом случае при интеграции придется разобраться с особенностями конкретного поставщика.


            Мы будем использовать недавно появившийся EXANTE Market Data API: начать разработку с ним можно просто и быстро, регистрация в системе не требует дополнительных подтверждений, а доступ к данным бесплатен. Пока API работает в режиме Tech Preview, но доступ открыт для всех желающих.

            Функциональность


            Определив спектр возможностей, нужно решить, что именно будет делать наш чат-бот. Существует масса вариантов: от отображения курсов валют до аналитики торговых стратегий по запросу на конкретный биржевой инструмент. Пока что не станем углубляться в детали финансовых алгоритмов и попробуем сделать что-то полезное, но при этом достаточно простое.

            Один из самых понятных финансовых инструментов — это акции компаний, торгующиеся на фондовых биржах. С ними и будем работать, выбрав для простоты фондовый рынок США, т. к. по нему легче всего получить фундаментальные данные, и торги там наиболее активны.

            Что интересует начинающего инвестора? Конечно же, выбор портфеля акций, вложив средства в которые, он сможет получить прибыль. Существует много способов выбирать акции: можно читать обзоры, можно ориентироваться на портфели лучших инвесторов, вроде Уоррена Баффетта или Билла Экмана, а можно пользоваться аналитическими методами. Один из общепринятых и самых распространенных методов — это оценка компании по метрике P/E (коэффициент цена/прибыль). P/E рассчитывается как отношение нынешней цены акции компании к показателю Earning Per Share (EPS, прибыль на акцию).

            Таким образом, наш чат-бот будет помогать инвестору решить, включать ли акции определенной компании фондового рынка США в свой портфель, исходя из текущей оценки коэффициента цена/прибыль. Высокий P/E относительно других компаний этой отрасли покажет, что у акций есть потенциал роста. Низкий же, напротив, даст понять, что в будущем компания может столкнуться с проблемами.

            Архитектура


            Итак, в качестве основного источника биржевой информации выберем EXANTE Market Data API (MD API). Для получения фундаментальной информации — информации об общем состоянии финансов компании — будем использовать открытый источник данных datatables.org, с которым можно работать через YQL (Yahoo! Query Language).

            Для реализации самого бота возьмем Python 3, а чтобы запустить его максимально быстро, применим фреймворк, поддерживающий все необходимые методы Telegram: python-telegram-bot.

            Для работы с Telegram будем использовать поллинг новых сообщений с сервера, т. к. в прототипе мы не рассчитываем на большой объем трафика.

            Заранее подумаем о том, чтобы приложение могло работать не только с одним клиентом. Для этого будем обрабатывать запросы в отдельных потоках. Для синхронизации и запуска потоков используем встроенные возможности фреймворка python-telegram-bot и примитивы синхронизации, доступные в Python.

            Все выбранные внешние сервисы доступны по HTTP, так что для работы с ними будем использовать известный модуль Requests.

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

            MD API требует авторизации запросов с помощью JSON Web Token, для генерации токенов возьмем библиотеку PyJWT.

            Подключение к API


            Для начала работы с MD API нужно зарегистрироваться на сайте EXANTE для разработчиков.

            После регистрации на портале становится доступным дэшборд с данными для доступа и управлением приложениями. Создадим там приложение для нашего бота:

            Самого бота заведем так, как описано в документации к Telegram, через переписку с роботом BotFather:

            Реализация


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

            — Привет, робот, сегодня в новостях слышал об AAPL, кажется, это какая-то фруктовая компания, думаю вложить туда деньги, что скажешь?
            — Акции AAPL (Apple Inc, биржа NASDAQ) имеют текущую оценку P/E 14, цена акции $117,06
            — Спасибо, а что насчет NVDA и GOOG?
            — NVDA (Nvidia Corp., NASDAQ): P/E 69, цена $105.7
            GOOG (Alphabet Inc., NASDAQ): P/E 29, цена $796.42

            Инициализируем бота и создаем обработчики сообщений:

            # -*- coding:utf-8 -*-
            
            import re
            from sys import path
            
            from configparser import ConfigParser
            
            from telegram import ParseMode, Emoji
            from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
            
            
            config = ConfigParser()
            config.read_file(open('config.ini'))
            
            # Create telegram poller with token from settings
            up = Updater(token=config[‘Api’]['token'])
            dispatcher = up.dispatcher
            
            # Welcome message
            def start(bot, update):
                msg = "Hello {user_name}! I'm {bot_name}. Ask me about stocks!"
            
                # Send the message
                bot.send_message(chat_id=update.message.chat_id,
                                 text=msg.format(
                                     user_name=update.message.from_user.first_name,
                                     bot_name=bot.name))
            
            def process(bot, update):
                msg = "I will try to show info on {tickers}"
                tickers = re.findall(r'[A-Z]{1,4}', update.message.text)
            
                bot.send_message(chat_id=update.message.chat_id,
                                 text=msg.format(tickers=", ".join(tickers)))
            
            def main():
                # Add handlers to dispatcher
                dispatcher.add_handler(CommandHandler("start", start))
                dispatcher.add_handler(MessageHandler(Filters.text, process))
            
                # Start the program
                up.start_polling()
            
                up.idle()
            
            if __name__ == '__main__':
                main()
            

            Сейчас наш бот уже умеет выделять тикеры акций, но ничего больше с ними сделать не может.

            Напишем интерфейс для работы с Market Data API и генерации токенов. Используем документацию и руководство по авторизации.

            import jwt
            
            # token expiration time in seconds
            EXPIRATION = 3600
            
            class MDApiConnector():
                token = (None, None)
                algo = "HS256"
            
                def __init__(self, client_id, app_id, key):
                    self.client_id = client_id
                    self.app_id = app_id
                    self.key = key
            
                def __get_token(self):
                    now = datetime.now()
            
                    # if there is token and it's not expired yet
                    if self.token[0] and (now - self.token[1]).total_seconds() < EXPIRATION:
                        return self.token[0]
            
                    claims = {
                        "iss": self.client_id,
                        "sub": self.app_id,
                        "aud": ["symbols", "ohlc"],  # NB: only allowed scopes can be accessed
                        "iat": int(now.timestamp()),
                        "exp": int(now.timestamp()) + EXPIRATION
                    }
            
                    new_token = str(jwt.encode(claims, self.key, self.algo), ‘utf-8’)
                    self.token = (new_token, now)
            
                    return new_token
            

            Полный код всех модулей доступен в репозитории: http://ift.tt/2imBZk6

            Добавим отдельный поток, который будет периодически запрашивать объемные данные по акциям:

            class DataStorage(Thread):
                def __init__(self, connector):
                    super().__init__()
                    self.connector = connector
                    self.stocks = {}
            
                def run(self):
                    while True:
                        timeout = 15 * 60  # 15 minutes
                        try:
                            self.stocks = connector.get_stocks()
                        except Exception as e:
                            logger.error(e)
                            timeout = 30  # re-read in case of exception
            
                        time.sleep(timeout)
            

            Метод работы с API для получения списка акций США может выглядеть так:
            def get_stocks(self):
                    stocks = self.__request("/types/STOCK")
                    return {x['ticker']: {"id": x["id"], 
                                          "exchange": x["exchange"], 
                                          "description": x["description"]}
                            for x in stocks if x.get("country") == "US"}
            
            

            После запуска этого потока и обращения к нему из обработчика сообщения, бот сможет вывести больше полезных данных (P/E здесь пока еще заглушка):

            Добавим запрос Earning Per Share, для этого сделаем небольшую обертку над YQL с кэшированием (в скором будущем мы сможем заменить этот вызов на аналогичный из MD API), которая запросит значение «EarningsShare» для выбранной акции.

            Теперь мы можем вывести полученный показатель EPS:


            Осталось последнее: получить текущую цену акции. Для большей производительности нам следовало бы подписаться на поток обновлений с ценами, но для прототипа можно выбрать более простой способ: запрашивать последнюю дневную «свечу» — так называют элемент графика цен, популярного среди трейдеров.

            Пример свечного графика соотношения индекса DJI и цены на золото по годам

            «Свеча» строится для определенного периода (например, дня или часа) и на одном рисунке объединяет четыре цифры: цену на начало периода, максимальную и минимальную цену за период и цену на момент окончания периода. Сокращение OHLC, обозначающее такую свечу, как раз и расшифровывается как Open-High-Low-Close. Цена Close самой последней свечи будет соответствовать текущей цене акции.

            Метод получения последней свечи может выглядеть так:

              def get_last_ohlc_bar(self, symbolId):
                    # NB: we use internal symbolId, not ticker
            
                    # 86400 (sec) - day duration
                    ohlc = self.__request("/ohlc/%s/86400" % symbolId, {"size": 1})
                    return ohlc[0]
            

            Собрав вместе все вызовы, мы получим такой код обработки одного тикера:
                    stock = storage.stocks.get(ticker)
                    eps = fundamendal_api.request(ticker).get('EarningsShare')
            
                    price = api.get_last_ohlc_bar(stock['id'])
                    ratio = Decimal("%.4f" % price['close']) / Decimal(eps)
            
                    msg = "{ticker} ({name}, {exchange}): EPS {eps}, P/E {ratio}, цена ${price} \n".format(
                        ticker = ticker,
                        name = stock['description'],
                        exchange = stock['exchange'],
                        ratio = "%.2f" % ratio,
                        price = price['close'],
                        eps = eps
                    )
            

            И теперь наш бот стал действительно полезен! Он может рассказать о текущем положении дел на рынке акций и даже кое-что посоветовать:

            Развитие проекта


            Текущий проект можно найти по адресу http://ift.tt/2imBZk6

            Дальнейшее развитие возможно по многим направлениям. К примеру, можно воспользоваться потоком данных о нынешней цене акции из MD API (/md/1.0/feed) и не запрашивать цену каждый раз из «свечек», а просто брать ее из внутреннего кэша, куда та будет попадать при обновлении потока.

            Можно добавить боту мониторинг и аналитику (например через botan.io), а также развернуть его на каком-нибудь облачном хостинге, вроде Heroku или Google App Engine.

            Бота можно сделать более «живым», добавив больше вариантов ответов, а также научить его отображать графики изменения цен, чтобы дать инвестору еще больше информации для анализа. Можно добавить любые другие метрики для оценки акций, сохранять портфель в данных робота, чтобы держать инвестора в курсе всех изменений, и расширить функциональность — например, на российский рынок акций.

            Заключение


            Подключив EXANTE Market Data API и воспользовавшись открытой фундаментальной информацией, за короткий срок мы разработали функционального робота, который поможет пользователю быстро оценить ситуацию на рынке. В процессе работы мы узнали о некоторых способах оценки акций на рынке и о терминологии, используемой в биржевой торговле.

            Кроме того, мы рассмотрели возможности развития, и даже у такого небольшого робота их немало. Есть еще много способов применения market data — и много пользователей, которые заинтересуются вашими финансовыми приложениями.

            В феврале EXANTE проведет хакатон, посвященный работе с рыночными данными с помощью EXANTE Market Data API. Авторы лучших чат-ботов и приложений получат призы, и сейчас как раз есть время подготовиться :) Подробнее о мероприятии напишем чуть позже.

            А какие API используете вы? Что бы вы хотели делать с рыночными данными?

            Комментарии (0)

              Let's block ads! (Why?)

              Как работают ИТ-специалисты. Петр Зайцев, генеральный директор и основатель Percona

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

              Будет интересно выяснить, что их объединяет, в чем они противоречат другу другу. Возможно, их ответы помогут выявить какие-то общие закономерности, полезные советы, которые помогут многим из нас.

              Сегодня наш гость — Петр Зайцев, генеральный директор, основатель Percona. Он считает себя не самым организованным руководителем. Более того, Петр, будучи человеком технического скалада, называет себя «нетипичным СЕО».

              Чем занимаетесь в компании?

              Я занимаюсь как стратегической частью управления компанией, так и нашими продуктами – сервисами и open source. Я, наверное, нетипичный СЕО, потому что обычно гендиректор уделяет больше времени продажам и маркетингу.

              Несколько лет назад я долго размышлял над этим вопросом: стоит ли мне быть ближе к СТО и нанять СЕО, или нужно построить отношения в команде так, чтобы она могла работать со мной как с СЕО, несмотря на то, что я человек технического склада. Я решил, что мне ближе второй подход.

              На мировом рынке есть такие люди, как Илон Маск или Марк Цукерберг, которые в душе такие «гики», несмотря на то, что занимают пост СЕО. В этом году, например, Марк Цукерберг рассказывал о планах сделать себе робота, который будет помогать ему по хозяйству. Вот это классно – наш человек.

              Одно слово (словосочетание), лучше всего описывающее, как вы работаете:

              Жонглер.

              Я не самый организованный СЕО в мире. Мне удобно заниматься несколькими задачами параллельно.

              Сколько часов в сутки вы уделяете работе?

              С годами это менялось. Сейчас примерно 10 часов в рабочие дни, в выходные – меньше. Вообще, для человека, который работает головой, это сложный вопрос. Мы можем продумывать решения рабочих задач когда угодно и где угодно.

              Сколько часов вы спите?

              Обычно 7 часов. Иногда меньше.

              Вы завтракаете?

              Да, легкий завтрак – кофе и йогурт.

              Много времени уходит на дорогу?

              20-25 минут.

              Что еще делаете по пути на/с работы?

              Слушаю новости или образовательные подкасты.

              Каким todo-менеджером пользуетесь лично вы?

              Я пользовался несколькими, но лист бумаги для меня лучше всего.

              Каким таск-менеджером / issue-tracker’ом / репозиторием пользуетесь?

              Для разработки мы используем JIRA, репозиторий – Git.

              Какие инструменты, фреймворки вы используете для разработки?

              Jenkins – для continuous integration, Vagrant, Docker.

              Drupal – для веб-сайта, WordPress – для блога.

              Есть ли в вашей компании какие-то внутренние проекты, библиотеки и для чего они создавались?

              Самый большой проект, который мы создали, – система тайм-трекинга и учета информации о клиентах.

              Мы раньше делали такие внутренние проекты: например, специальный продукт для учета времени был сделан именно таким образом, как нам хотелось. С годами мы поняли, что поддерживать свой внутренний софт дорого и за стандартными решениями тяжело угнаться — в последние годы мы как можно больше всего переводим на стандартные системы — Zendesk, Salesforce, Liquid Planner и так далее.

              Что вас раздражает больше всего, когда вы работаете?

              Люди не в достаточной мере являются «роботами». Если компьютер делает в точности, что ему сказано, то люди могут не понять с первого раза. Объясняешь десять раз, потом тебя человек неправильно поймет, а если даже поймет правильно, все равно сделает по-своему.

              Какую профессиональную литературу вы бы могли порекомендовать?

              Мне нравится американский автор Patrick Lencioni. Он пишет книги про работу в команде. Очень хорошие книги, легко читаются.

              Еще одна книга, которую бы я порекомендовал, – это The Hard Thing About Hard Things. Там очень много детальных рекомендаций для бизнесменов.

              Кроме того, я читаю книги о том, как думают люди, и как думать лучше. Книги Nasstim Taleb — такие, как Black Swan, Antifragile или Halo Effect.

              Что предпочитаете: электронные читалки или бумажные книги?

              И то, и другое. Читать электронные книги получается чаще, но бумажные больше нравится, так как можно помечать ручкой и так далее.

              Какую технику (компьютеры, планшеты, смартфоны) и операционные системы вы предпочитаете на работе и дома?

              Я использую Windows на ноутбуке. Наверное, в нашей области сейчас более популярен Mac, но меня устраивает. Мне нравится, что в этом случае можно выбирать не из трех моделей лэптопов, а из тридцати. По этой же причине я использую Android.

              На работе есть тестовый стенд, где я использую несколько маленьких серверов на Linux.

              Вы слушаете музыку, когда работаете?

              Нет, я отвлекаюсь.

              Какой лайфхак позволяет вам быть эффективнее?

              Многие советуют: вместо того, чтобы сфокусироваться на чем-то маленьком, на том, что вам хочется сделать, наоборот, возьмите большую задачу. С одной стороны, это важно, но я считаю, что если у вас что-то «горит», то есть вам сильно хочется это сделать, нужно начать именно с этого. Лично мне так намного легче: потом уже я могу работать значительно эффективнее над большой, важной и нудной задачей, не отвлекаясь.

              Без каких приложений и сервисов не можете обойтись ни в работе, ни в личной жизни?

              Прежде всего, Google Docs. Не столько почта, сколько документы, потому что с ними можно коллаборативно работать.

              У вас пройден огромный путь. А кто-то сейчас стоит в начале этого пути. Что бы вы порекомендовали человеку, пытающемуся пройти тот же путь?

              Прежде всего, это фокус. У меня часто бывали проблемы с фокусом, поэтому нужно было дисциплинироваться. Ментор мне часто говорил: «Петя, ты любишь начинать проекты, но важнее научиться их заканчивать».

              Со временем у меня менялся подход. В начале работы я сильно фокусировался на возможностях. Но когда компания становится больше, прыгать туда-сюда будет сложно. Поэтому нужно формировать какую-то стратегию, чтобы достичь успеха.

              Еще очень важно терпение. Раньше мне казалось, что все очень просто. Я думал, что могу сделать все, что угодно, за уикенд. Поэтому нужно спокойнее и осторожнее планировать.

              И последнее: мне пришлось потратить время, чтобы понять, что все люди разные. У людей могут быть другие мотивации, и мозг работает по-другому. Если бы в компании были одни мои «клоны», мы, наверное, все передрались бы, а компания не смогла бы функционировать.

              Комментарии (0)

                Let's block ads! (Why?)

                [Из песочницы] Android Things


                Google представила обновленную платформу для интернета вещей — Android Things

                13 декабря Google официально объявила о выходе в релиз Developer preview своей платформы для интернета вещей с поддержкой разработки под Android. Теперь всем знакомым с Android разработкой будет еще легче войти в мир создания IoT устройств.

                Официально поддерживаются три типа устройств:


                Поддержка еще двух ожидается в ближайшее время:
                • Intel® Joule™ 570x
                • NXP Argon i.MX6UL

                Все что нужно для разработки приложения это Android Studio, и одно из устройств выше.

                Приложение


                image alt

                Структура приложение для Android Things

                Все примеры Вы можете посмотреть в официальном репозитории. Есть template для старта нового приложения.

                Как правило на устройства Android Things не могут устанавливаться несколько приложений, поэтому единственное приложение автоматически будет запускаться при старте устройства.

                Для отображения приложение использует тот же UI toolkit что и обычное Android приложения, не поддерживает system status bar и navigation buttons. Наличие дисплея не обязательно для работы приложения, а все события автоматически доставляются до activity приложения.

                В gradle-файле приложения устанавливаем minSdkVersion 24 и добавляем provided-зависимость:

                provided 'com.google.android.things:androidthings:0.1-devpreview'
                

                В AndroidManifest в application надо указать:
                <uses-library android:name="com.google.android.things"/>
                

                В приложении всего одна activity которая запускается при старте устройства и уничтожается при выключении.

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

                <intent-filter>
                        <action android:name="android.intent.action.MAIN"/>
                        <category android:name="android.intent.category.IOT_LAUNCHER"/>
                        <category android:name="android.intent.category.DEFAULT"/>
                </intent-filter>
                
                

                Доступны так же стандартные темы оформления: Theme.DeviceDefault

                Периферия


                Платформа поддерживает набор интерфейсов оборудования: GPIO, PWM, I2C, SPI, UART. Библиотеки для подключения различный периферийных устройств доступные из коробки:
                • RGB LED apa102
                • Сенсор температуры bmx280
                • Кнопка
                • Touch сенсор cap12xx
                • UART GPS
                • Дисплеи HT16K33, TM1637, OLED дисплей ssd1306
                • Акселерометр MMA7660FC
                • Сервопривод
                • Спикер
                • Rainbowhat

                Есть возможность для написания своего драйвера. Тут Google представляет концепцию user driver, которая предполагает что драйвера к датчикам будут поддерживать уже существующий сервис работы с драйверами, что позволит легко использовать их на различных платформах.

                Почти поровну

                Поддерживается три типа драйверов:


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

                Для начала необходимо создать объект драйвера. Драйвер датчика должен наследовать абстрактный класс UserSensorDriver и переопределить всего два метода:

                read — вызывается для получения новых данных от сенсора и должен возвращать данные в виде объекта класса UserSensorReading.
                setEnabled — используется для возможности перехода в режим сна или экономии энергии.

                Далее с помощью UserSensor.Builder создаем свой объект UserSensor, указываем его имя, производителя, задаем свой тип и передаем ему драйвер. Регистрируем сенсор в менеджере UserDriverManager и не забываем отключить регистрацию при закрытии приложения.
                Подробнее почитать о создании драйверов можно тут.

                Как видно из демо примеров, приложение состоит из двух основных частей. Activity в которой и происходит вся работа и вспомогательный класс BoardDefaults, который возвращает строковые название пинов к которым подключены те или иные устройства в зависимости от платформы на которой запущено приложение.

                Для работы с поддерживаемыми устройствами в системе предусмотрен PeripheralManagerService с помощью которого можно получить список доступных пинов/шин для конкретной платформы, а так же указать на какой пин подключено наше устройство.

                Каждый тип устройств имеет свой набор методов для управления и интерфейсов обратной связи.

                Пример подключения светодиода
                    PeripheralManagerService pioService = new PeripheralManagerService();
                                mLed = pioService.openGpio(BoardDefaults.getLedGpioPin());
                                mLed.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
                

                И передаем boolean значение
                                mLedGpio.setValue(value);
                
                

                Пример подключения кнопки
                     mButtonInputDriver = new ButtonInputDriver(
                                BoardDefaults.getGPIOForButton(),
                                Button.LogicState.PRESSED_WHEN_LOW,
                                KeyEvent.KEYCODE_SPACE);
                       mButtonInputDriver.register();
                
                

                И далее ловим нажатие кнопки
                @Override
                    public boolean onKeyUp(int keyCode, KeyEvent event) {
                        if (keyCode == KeyEvent.KEYCODE_SPACE) {
                            // button pressed
                            return true;
                        }
                        return super.onKeyUp(keyCode, event);
                    }
                
                

                Подробнее можно посмотреть пример с подключением большого числа сенсоров.

                Возможности платформы


                Сначала об ограничениях. В платформе не доступны многие стандартные приложения и контент-провайдеры, а так же некоторые Google API
                Intents Google Api
                CalendarContract AdMob
                ContactsContract Android Pay
                DocumentsContract Firebase App Indexing
                DownloadManager Firebase Authentication
                MediaStore Firebase Dynamic Links
                Settings Firebase Invites
                Telephony Firebase Notifications
                UserDictionary Maps
                VoicemailContract Play Games
                Search
                Sign-In

                Так как в связи с отсутствием status bar, не поддерживаются уведомления, NotificationManager API не доступны.

                Но и доступно не мало:

                Cast
                Drive
                Firebase Analytics
                Firebase Cloud Messaging (FCM)
                Firebase Crash Reporting
                Firebase Realtime Database
                Firebase Remote Config
                Firebase Storage
                Fit
                Instance ID
                Location
                Nearby
                Places
                Mobile Vision

                И тут не может не порадовать наличие поддержки Firebase Realtime Database, Firebase Analytics и FCM, которые с легкостью позволят управлять Android Things устройствами через интернет и собирать данные с них.

                Так же нет необходимости запрашивать разрешения в процессе работы, все разрешения, указанные в AndroidManifest, автоматически будут даны.

                Google Weave


                Одновременно с Android Things Google представила платформу Weave. Платформа включает в себя:
                • Weave Server, который осуществляет регистрацию устройств, обмен и хранение данных, а так же интеграцию с другими сервисами Google;
                • SDK для подключения устройств к Weave серверу. Пока поддерживаются платформы: Linux, Qualcomm QCA4010, и Marvell MW302;
                • Набор инструментов для разработки и интеграции, включая специальное приложение.

                Weave в настоящее время поддерживает: HVAC контроллеры, лампочки, розетки, ТВ и выключатели.

                Для получения доступа ко всем возможностям платформы необходимо вступить в группу Google.

                Weave уже используются в устройствах Philips Hue and Samsung SmartThings и есть договоренности об использовании платформы еще рядом производителей Belkin WeMo, LiFX, Honeywell, Wink, TP-Link и First Alert.

                Стоимость


                Raspberry Pi 3 model B ~ 4 000р. + блок питания от 500р. (Intel® Edison with Arduino Breakout Kit ~ 7500р. + блок питания от 800р.) + SD card 32GB ~ 700р. Доска для прототипирования от 700 р.

                В итоге отличный новогодний подарок Вам обойдется около 7 000 рублей. А также имеются уже готовые наборы, включающие Raspberry Pi 3 с некоторым набором сенсоров, примерно за эту же стоимость.

                Всех с наступающим Новым годом!

                Официальный сайт Android Things
                Github репозиторий с примерами
                Официальный сайт Google Weavr

                Комментарии (0)

                  Let's block ads! (Why?)

                  Топ-10 ключевых анонсов от Microsoft в 2016 году

                  Чем «interface» отличается от «междумордия»: наш подход к документированию и локализации программных продуктов


                  Однажды в технической документации к Parallels Desktop нам потребовалось использовать фразу «жёсткий диск виртуальной машины». На английском языке это звучит: virtual machine hard disk. Наш прошлый технический писатель ошибся всего в одной букве в одном слове, но смысл получился диаметрально противоположный. Мы этого заметили не сразу и в какой-то момент наша техническая документация, локализованная на многих языках мира, содержала нетленное: virtual machine hard dick. Был грандиозный скандал, после которого мы ужесточили проверку текстов. Под катом — рассказ нашего технического писателя Андрея Старовойтова о том, где обитают технические писатели, на что их ловить и как Parallels документирует и локализует свои продукты.

                  Возможно, у вас возникнет вопрос — а зачем мне, разработчику/программисту/тестировщику, знать о том, как создаются и локализуются документация и интерфейс? Всё очень просто: жизнь может внезапно повернуться к вам так, что сегодня вы программист, а уже завтра запускаете свой стартап, в котором вы и швец, и жнец, и технический писатель. Также не исключено, что заняв менеджерскую должность вам внезапно придётся контролировать процесс разработки технической документации.

                  Часть 1: Где найти технического писателя или гуманитарий в тылу у технарей


                  Технических писателей не готовят в ВУЗах. Если понадобился такой специалист, можно пригласить его из-за рубежа, или «вырастить» в компании. Ниже мы поподробнее остановимся на этих вариантах.

                  Иностранный специалист


                  Плюсы:
                  Если вы планируете продавать продукт за рубежом и вам нужна документация на английском языке, носитель языка более качественно опишет приложение. Нельзя сказать, что отечественный сотрудник со знанием языка сделает это обязательно плохо, но если подходить к вопросу с точки зрения перфекционизма, то по некоторым фразам, оборотам, построению предложений иностранные пользователи могут понять, что документацию писал не носитель.

                  Минусы:
                  Во-первых, иностранному специалисту придется больше платить. А во-вторых, не каждый иностранец согласится приехать на работу в Россию. Если же он будет работать удаленно, в отрыве от разработчиков, то возможны опоздания в сроках подготовки документов, и технические неточности, так как удаленно всегда сложнее выяснить технические детали, нежели если поговорить с программистами напрямую.


                  Писатель «которого вырастили»


                  Тут встает вопрос, из кого выращивать – технарь или гуманитарий? Конечно, все зависит от конкретной ситуации, но давайте посмотрим на основные моменты.

                  «Технарь»
                  Плюсы:
                  Технарь лучше понимает начинку и технические детали или же ему проще разобраться.

                  Минусы:
                  Не каждому технарю захочется возиться с документацией, потому что разработчик чаще сконцентрирован на какой-то узкой области и видит себя Скульптором, а не Евгением Онегиным, «который может коснуться до всего слегка с ученым видом знатока».

                  «Гуманитарий»
                  Плюсы:
                  Все зависит от конкретного случая, но гуманитарий может лучше описать продукт, так как лучше владеет языком. И еще такой момент, разработчик может описать функцию или фичу двумя предложениями, так как с его багажом знаний ему и так все понятно. Для покупателя продукта такого описания может оказаться недостаточно. У гуманитария, как неспециалиста, при описании возникнут разнообразные вопросы. Если он найдет на них ответы и опишет функцию продукта так, чтобы самому было понятно, то такая документация окажется более понятна для пользователя. Хотя опять же, все зависит от конкретной ситуации, если руководство написано для администраторов, будет излишне объяснять им что такое IP адрес.

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

                  Личный опыт
                  image — Я попал в Parallels весьма прозаично. После школы учился в педагогическом колледже в городе Серпухове на преподавателя английского языка. После в Московском Государственном Лингвистическом Университете им. Мориса Тореза. Когда на третьем курсе университета встал вопрос серьезной работы, я уже успел побывать курьером по развозу DVD, учетчиком на складе, начальником склада, менеджером по продажам. Все это было хорошо, но желание зарабатывать на жизнь английским языком было крепче. В преподавание не пошел, так как хотелось поработать в какой-нибудь прикладной области – нефтянка или IT.

                  Как-то на одном из сайтов по поиску работы я увидел вакансию – помощник технического писателя в компанию SWsoft с возможность карьерного роста. В объявлении говорилось об участии в создании документации для компьютерных программ. Писать документацию требовалось сразу на английском. Для меня это было что-то совершенно новым и заинтересовало. Я отправил резюме, прошел собеседование, написал сочинение на свободную тему и так стал junior technical writer.

                  Сначала было непросто. Будучи гуманитарием до мозга костей, при написании первых топиков, казалось, что все вокруг говорят на каком-то птичьем языке. Я совершенно не знал терминов. Разговор с девелоперами первое время выглядел примерно так:

                  — Здравствуйте, я новый технический писатель. Мне надо описать вот эту функциональность. Не могли бы вы чуть поподробнее рассказать как она работает?
                  — А, ну тут все просто, клиент «коннектится», если «сервак» не дохлый, все нормально. Если что, можно «попинговать». Бывает «бага стреляет», «контейнер бсодится», но тут «патчик» можно накатить. Возьми вот этот «экзешник», он у тестировщиков на «репе» лежит. Понял? Ну молодец.

                  или так:

                  — Мне вот тут надо фичу описать, она связана с Active Directory. Не могли бы вы рассказать что это такое?
                  — Да это тоже самое что и LDAP на Линуксе.

                  Поначалу записывал все эти термины в тетрадочку, затем шел «гуглить» значение. После этого опять шел к разработчикам или тестировщикам и спрашивал по-новой. Первые полгода, в свободное от работы и учебы время, изучал терминологию, читал что такое автоматизация, виртуализация, контейнеры, виртуальные машины, оперативная память, процессор, IP адрес, DHCP, и т. д. Потом, неожиданно количество перешло в качество и я стал свободнее себя чувствовать в этой сфере. Если что-то не понимал, мне хватало гугла для того, чтобы схватить основную мысль, а к девелоперам шел уже в основном за деталями.

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

                  Часть 2: Как мы создаем техническую документацию


                  Над созданием документации у нас трудятся 3 человека – двое в России и один сотрудник в США, для которого английский язык родной. Для написания технических книг, мы используем продукт AuthorIT. В нем довольно удобно работать. Библиотека с книгами лежит на сервере. У каждого писателя на компьютере стоит клиентская часть, с которой он подключается к библиотеке. Это позволяет нескольким писателям работать над одной книгой. Применение вариантов позволяет легко создавать книги для новых версий продуктов на основе старых.

                  Мне сложно сказать что-либо о других продуктах, в которых можно создавать документацию, поскольку исторически сложилось, что мы работаем в AuthorIT. Нас он пока устраивает, а переходить на другой продукт просто из любопытства может оказаться удовольствием недешевым. Например, та же подписка на AuthorIT на 3 человек обойдется в $375 в месяц и выше.

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

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

                  Процесс создания документации построен следующим образом:
                  1) Маркетинг с менеджерами обговаривают список функциональностей и улучшений, которые будут внедрены в новой версии продукта.
                  2) Для каждой задачи менеджер пишет детальное описание.
                  3) После того, как программист внедряет функциональность, я ставлю последнюю версию программы на компьютер, читаю описание, пробую как новинка работает, и описываю ее в руководстве. Если возникают какие-либо вопросы, общаюсь с менеджерами или разработчиками.
                  4) Я описываю новый функционал на английском, после чего отправляю топики нашему иностранному писателю на проверку. Он читает и если есть необходимость вносит какие-либо правки. Вроде бы я неплохо знаю английский, но все равно носитель языка иногда может выразиться более лаконично и емко.
                  5) После проверки, иностранный писатель присылает топики мне, я заливаю их в базу и публикую документы в необходимые форматы – в основном это PDF и XHTML для контекстной справки (это когда жмешь на экране иконку со знаком вопросы и привязанный к этому скрину хелп топик открывается в браузере).
                  6) Когда английская документация готова, я отсылаю ее на перевод. О том как и на какие языки мы переводим я расскажу ниже.

                  Какие документы создаются для продукта:
                  User’s Guide – это самая большая книга для продукта, в которой описывается весь функционал, хитрости и решения возможных проблем. Ориентирован на большинство пользователей.
                  Getting Started Guide – это короткий документ, в котором описана процедура установки и основные шаги, необходимые для начала работы с продуктом. Ориентирован на знакомство с продуктом и пользователей, которые обладают неким опытом и хотят побыстрее начать работу с приложением, не внедряясь в дополнительные настройки и тонкости.
                  Readme – обычно это текстовый файл, который создается для каждого релиза, хотфикса и апдейта. В нем описано то, что было сделано нового, что улучшено и какие проблемы решены.
                  Knowledgebase articles – это статьи для так называемой базы знаний. В них описаны или какие-то моменты, которые вызывают частые вопросы у пользователей или временные решения известных проблем.

                  Так же существуют различные другие виды книг, такие как:
                  Licensing Guide (описывает как создать аккаунт, управлять своим ключом или подпиской и т. д.)
                  Administrators guide (документ для людей с техническим опытом для развертывания продукта в больших компаниях)
                  Training manual (документ для людей, которые обучают пользователей как работать с продуктом)
                  Command Reference Guide (в нем описаны команды для текстовой строки и даны примеры их применения)
                  API Reference Guide (в таких книгах документируют API).

                  Какие инструменты мы используем для создания документации:
                  AuthorIT – программа для создания и работы над книгами.
                  Adobe Photoshop – для создания и работы над скриншотами для документации.
                  Microsoft Visio — для создания схем.
                  Microsoft Word и Adobe Acrobat – для публикации документов в .docx формат и последующей генерации в PDF.

                  В работе по созданию документации бывают разные курьезы. В основном связанные или с невнимательностью писателя или если что-то делается в спешке и банально упустили. Например, были случаи когда выпускалась готовая документация, в которой остались не удаленные комменты писателя, например «Уточнить у Васи как эта херня работает».

                  А еще бывает, что сами писатели прикалываются в документации для внутреннего пользования. Некоторые люди считают, что документация никому не нужна, так как ее никто не читает. Иногда писатель в каком-нибудь неофициальном документе для компании может написать в тексте инструкций – «кто первым это прочтет и позвонит мне – выиграет пиво».

                  Часть 3: Как технический писатель может участвовать в создании GUI


                  В процессе работы над фичами, разработчикам зачастую надо придумать название опции, меню, дескрипшн под опцией или сообщение об ошибке. Так как мы делаем гуй сразу на английском, девелоперы поручают эту задачу мне. Я читаю описание фичи, спрашиваю девелоперов и менеджеров что нам нужно сказать, выясняю детали и предлагаю свой английский вариант. Если он технически верен, отправляю его на утверждение нашему иностранному писателю и сообщаю ему все детали, которые выяснил у девелоперов. Тот в свою очередь или утверждает мой вариант или предлагает что-то свое. Если финальный вариант всех устраивает, его заливают.

                  В процессе создания гуя, мы придерживаемся следующих пунктов:
                  1) Нужно стараться делать названия опций понятными и короткими, чтобы избежать последующих проблем с их локализацией, когда перевод не влезает. Например, у нас есть опция, которая тормозит курсор мыши у границы окна виртуальной машины. Это было сделано, чтобы юзер в Windows 8 мог легче открыть дополнительные меню, которые находятся у границы. Без этой опции юзер зачастую просто выводил курсор за границу и приграничное меню не показывалось. Так вот, долго думали как назвать эту опцию, получалось или слишком длинно или не совсем понятно. В итоге остановились на «Mouse sticks at window edges». Конечно бывают случаи, когда сложно придумать идеальное название для опции, в таких ситуациях приходится выбирать более-менее приемлемый вариант и надеяться на то, что если юзер не поймет, то почитает в документации.
                  2) Если в сообщении используются сложные термины или описан трудоемкий процесс как решить какую-то проблему, есть смысл дать ссылку на КБ статью или какой-то другой ресурс, где есть более детальное и подробное описание или объяснение.
                  3) При создании сообщения, надо концентрироваться не на том, что не получилось что-то сделать, а на том, что надо сделать чтобы желаемый результат был достигнут.

                  Часть 4: Перевод технической документации и GUI


                  После того, как началась разработка новой версии программы, обычно к Beta 1/Beta 2 накапливается первая партия хелп топиков и фраз гуя, которые можно отсылать на локализацию.
                  На мой взгляд, очень здорово, если тот самый писатель, который написал топики и помогал делать гуй, и будет управлять переводами и общаться с переводческой конторой. Такой человек грамотно планирует работу, лучше знает сроки когда что будет написано или как скоро что-то надо описать. Он знает значение гуевых фраз и может легче и быстрее ответить на вопросы переводчиков.

                  Помню мы раньше использовали разделение – есть люди, которые пишут, и есть человек, который занимается только локализацией. В итоге не всегда процессы проходили эффективно. Например, писатели описали фичи, свои таски в Jira закрыли и успокоились. Но забыли отметить все топики, которые были изменены. В итоге менеджер локализации отправил на перевод не все и в результате приходилось в дикой спешке допереводить пропущенное. Или менеджер по локализации отправил гуй на перевод, но он его не создавал, и не может ответить на многочисленные вопросы переводчиков. Начинает дергать разных людей, а их еще надо найти, потому что часть гуя делали сервер тим, часть – девайсы, часть гуевщики, часть – интеграторы, короче потеря времени и не детальные ответы – как результат – недостаточное качество переводов.

                  Мы переводим документацию и гуй наших продуктов на следующие 12 языков: немецкий, французский, итальянский, испанский, польский, чешский, русский, португальский (бразильская версия), японский, корейский и две версии китайского — упрощённый и традиционный тайваньский.

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

                  Собственные переводчики


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

                  Минусы:
                  Как правило, наиболее активная стадия разработки продукта, когда надо делать много переводов, длится 3-4 месяца. В такой ситуации необходимо все считать, потому что может оказаться просто экономически невыгодно держать переводчиков на постоянной основе.

                  Переводческая контора


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

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

                  Мы пользуемся услугами одной из европейских компаний. У неё свой корпус переводчиков на разные языки.

                  Все текстовые материалы отправляются подрядчику. Форматы могут быть самыми разными:

                  • при локализации GUI — .txt-файлы, .strings-файлы, .xml-файлы, .xliff-файлы,
                  • при локализации документации — .docx-файлы, .xml-файлы

                  В первую очередь надо локализовать GUI. К каждой порции гуя на перевод я готовлю подробные комментарии для переводчиков – по каждой фразе. В комментариях описываю что это за фраза, как ее переводить – инфинитивом или императивом, надо ли переводить как можно короче (особенно если это кнопка) и если да, то во сколько символов надо уместиться. Также шлю переводчикам скриншоты, чтобы они могли посмотреть как опция или сообщение выглядит в гуе.

                  Почему в первую очередь надо переводить гуй


                  Дело в том, что переведенные фразы попадают в так называемую память переводов – translation memory. Из этой памяти они впоследствии будут браться, если в последующей порции фраз на перевод окажется точно такая же. Например, мы перевели гуй и утрясли опции по длине. После этого я отправляю на перевод документацию, в которой эти же опции описываются. Так вот, перевод этих опций для документации будет взят из translation memory, и таким образом фразы и в гуе и в документации будут переведены одинаково. Если же я сначала переведу документацию, а потом гуй, то если в гуе опция будет слишком длинной, мне придется править и в гуе и в документации, чтобы везде было консистентно, а это лишний геморой.

                  По мере готовности переводчики присылают мне переведённые материалы, я импортирую их в базы, откуда потом локализованный гуй и документация попадают в билд.

                  Как работает переводческая контора?


                  Получив от нас материалы, подрядчик прогоняет их через свою базу уже выполненных переводов — так называемую translation memory. Система ищет, есть ли в новом материале данные, которые были когда-то переведены. По мере нахождения эти готовые фрагменты вставляются в текст. Допустим, если из четырёх присланных абзацев три уже были переведены для предыдущего релиза, то достаточно перевести только четвёртый абзац, а остальные взять их базы данных. Это экономит и время, и деньги. Так что дольше всего переводятся самые первые порции материалов, где больше всего изменений и нового текста.

                  В работе с локализационными компаниями есть одна особенность: им нужно единовременно присылать как можно больше материала. Если делать слишком маленькие по объёму заказы, то это может оказаться гораздо дороже.

                  Почему так происходит?


                  У каждой локализационной компании прописаны свои минимальные объёмы на перевод. Если после прогона через их базу данных окажется, что нужно перевести слишком мало текста, то счета выставляются не за переведённые слова, а за почасовую работу переводчиков. А поскольку с приближением к дате релиза порции текстов, требующих локализации, становятся всё меньше, приходится лавировать, придерживая материалы, чтобы накопить побольше и не переплатить. При этом важно не сорвать сроки, выкатив за неделю до релиза слишком большой заказ на перевод.

                  Стоимость локализации


                  Наверное, вас интересует, сколько же компании тратят на локализацию своих продуктов? Это сильно зависит от объёмов и выбранных языков. Например, стоимость перевода одного слова на польский язык — $0,14, на немецкий — $0,23, на французский — $0,21. У нас большие и сложные продукты, с увесистой документацией, которую нужно переводить на 12 языков. Поэтому общая стоимость локализации в среднем составляет $10-60 тыс. Причём сюда не входят расходы на перевод статей из баз знаний (knowledge base), в которых описываются различные методики работы, а также локализацию изменений на сайте.

                  «Джентльменам верят на слово»


                  Учитывая разнообразие языков и высокую стоимость работ, как можно оценить качество перевода? А вдруг подрядчик просто прогнал текст через Google Translate и подрихтовал результат?

                  Дело в том, что в сфере локализации крайне важна репутация. Когда компании ищут подрядчиков для перевода документации и интерфейсов, они подходят к этому очень тщательно. Например, мы выбирали примерно из 15 компаний: всем разослали тестовые задания, а затем проверяли сделанные переводы по своим сотрудникам из разных стран, понимающих эти языки. Также пристальное внимание мы уделяли отчётности о выполненной работе: насколько подробно расписано, сколько слов переведено, сколько обнаружено новых слов, учитываются ли случаи, когда нужно переводить лишь часть предложения, и так далее.

                  В конце концов мы выбрали своим подрядчиком одну из компаний и начали с ней работать. Но это не означает, что мы с тех пор верим им на слово. Качество переводов регулярно проверяется:

                  • нашими сотрудниками, понимающими соответствующие языки,
                  • переводчиками самого подрядчика. Дело в том, что там переводят одни, а вычитывают по нашей просьбе другие.

                  Наверняка вы скажете, что проверять работу одной компании нужно у специалистов другой. Но дело в том, что локализационные компании отчаянно борются за клиентов. И если мы кому-то пришлём тексты и попросим их оценить, то нам сразу скажут, что переведено из рук вон плохо, давайте мы сделаем гораздо лучше. Собственно, попытки нас переманить не прекращаются до сих пор.

                  Иногда, когда выходит большой релиз, не всегда получается проверить документацию, локализованную незадолго до дедлайна. Тогда приходится на свой страх и риск выпускать как есть. Но в таких случаях мы тесно работаем с поддержкой: если в документации есть какие-то косяки, на которые поступают жалобы от пользователей, то мы сразу обращаемся к переводчикам и переделываем. К счастью, такое случается редко.

                  Проблемы с переводами


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

                  1) Невнимательный переводчик – если во фразе гуя есть переменная, невнимательный переводчик может пропустить ее часть. Например, у вас переменная (%1)s, а в переводе получите (%1). В итоге фраза будет выглядеть не так, как надо.

                  2) Переводчик задумался – все мы люди, бывает, что переводчик что-то переведет неправильно, причем что-то довольно простое. Например фраза This file is not valid (Файл недействителен) будет переведена как «Файл не найден».

                  3) Слишком тщательный переводчик – такой переводчик переводит все, что видит. Тут надо объяснить, что переменную ProductName на надо переводить как «Имя продукта», иначе она ломается и в гуе имена продуктов не подставляются. Или же если он переводит .xml файл с документацией, то не надо переводить теги и , иначе потом такой xml не импортится в базу из-за разломанных тегов.

                  4) Сложный технический термин или аббревиатура– если в тексте на перевод есть что-то подобное, лучше сразу в комментариях обратить внимание переводчиков на это, описать что это такое и посоветовать погуглить, чтобы узнать как правильно это переводится на их язык. Иначе можно получить что-то далекое от нужно термина.

                  5) Косяки из-за отсутствия комментариев – если не делать комментарии для переводчиков, они могут задать вопросы не по всем непонятным моментам. В итоге может пострадать качество переводов. Например, у нас есть приложение Parallels Access, которое позволяет получить доступ к удаленным компьютерам с iOS и Android устройств. В другом продукте есть вкладка, которая позволяет скачать это приложение. Эта вкладка называется Access и не должна переводиться. Мы тогда не успели сделать комментарии, в итоге чехи и поляки быстренько ее перевели, где как «доступ», где «приступ».

                  6) Слишком ответственный переводчик – такой переводчик сам может вставлять знаки препинания, которые не надо вставлять. Например у нас в одном продукте двоеточие и точка в конце предложения вставляется автоматически – так написано в коде. В итоге мы отослали на перевод фразы без точек и двоеточий в конце. Переводчик в переводе сам решил поставить в конце точки, и у нас везде оказались двойные точки. Или переводчик может додумать и дописать текст фразы. Например, есть фраза Unable to save the license file. Я в комментарии объясняю, что она показывается в том случае, когда по каким-то причинам мы не можем сохранить лицензионный файл для продукта Parallels Desktop. Приходит перевод – «Не удалось сохранить лицензию для Parallels Desktop.» Приходится объяснять, что додумывать не надо и лучше ограничиться фразой «Не удалось сохранить лицензию», так как в коде она может быть использована для других продуктов.

                  7) Слишком длинный перевод – получаешь бывает перед релизом порцию переведенного гуя, заливаешь переводы, а в гуе половина опций не влезает – слишком длинно перевели. Тут надо реагировать по ситуации – или срочно просить переводчиков сократить перевод, или просить девелоперов расширить окно, потому что если длинную фразу сокращать до «тыр.пыр.мыр.», то это получится некрасиво и непонятно.

                  8) Неправильно рассчитанные сроки – иногда бывают ситуации, когда отсылаешь файлы на перевод и думаешь – ну тут за 3 дня переведут, максимум. А тебе выкатывают срок – неделя, не меньше. Поэтому я взял за правило – к ожидаемому сроку прибавляй 3-4 дня на всякий случай.

                  9) Праздники в других странах – это тоже связано со сроками. Обычно локализационная компания предупреждает, и об этом надо помнить – где, когда и у кого государственные праздники. А то иной раз надо что-то срочно перевести на китайский, думаешь – ну это я мигом, а тебе говорят, что у них же новый год сейчас. Обещают попробовать найти выход но в результате подобная ситуация может тоже обернуться задержкой.

                  10) Разработчик – оптимизатор – иногда приходится вести войну с разработчиками. У них оптимизация кода — это идея фикс. Они очень любят многократно использовать одни и те же данные. Например, вставят в одном месте какую-то фразу или слово, а потом ссылаются из самых разных мест. У меня был такой случай. В приложении есть вкладка, на которой можно переназначать клавиатурные сочетания. В частности, там есть шорткат Ctrl+Alt+Delete. И ещё у нас есть менеджер снэпшотов, позволяющий удалять эти снэпшоты. Что характерно, кнопка так и называется — Delete. Разработчик, который писал этот менеджер, вместо того, чтобы назвать шорткат Ctrl+Alt+Delete и отдельно кнопку Delete, придумал оптимизацию: в одном месте кода назвал кнопку Delete, а шорткат назвал Ctrl+Alt+<вот эта кнопка>. И когда мы стали переводить интерфейс, кнопка Delete была переведена на все языки. В русскоязычной версии этот шорткат стал называться Ctrl+Alt+Удалить. Пришлось в коде прописывать отдельно названия кнопки и шортката. Другой пример. Когда мы выпускали Parallels Access, на начальном экране была фраза “Welcome to Parallels Access”. По идее, её нужно было прописать в коде как есть. Но поскольку во фразе использовались три разных шрифта, разработчики разбили её на три части: Welcome, to и Parallels Access. И при выводе на экран фраза собиралась из этих частей. Когда дело дошло до переводов, японцы офигели, но добросовестно перевели все три части по отдельности. Только проблема в том, что в японском языке текст читается справа налево. И вместо «Добро пожаловать в Parallels Access» у них получилось «Parallels Access в добро пожаловать». Пришлось менять код.

                  Проверка локализации перед релизом


                  Как бы тщательно не делались комментарии для перевода, а различные косяки все-таки бывают, поэтому перед релизом хорошо бы проверить качество локализации.
                  Проверять можно одним из следующих способов – или дать переводчикам программу и сценарии, по которым надо осуществить проверку, или предоставить скриншоты продукта и сценарии. Опять же, у каждого из них свои плюсы и минусы.

                  Проверка на живом билде


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

                  Минусы:
                  Этот тип тестирования более затратен в финансовом плане. Зачастую у переводчиков нет необходимого оборудования, поэтому надо им заплатить дополнительно, чтобы они его арендовали. Также они потратят больше времени на проверку живого билда, за каждый час надо заплатить. Плюс, когда они начинают, гонять живой билд, у них как правило что-то не получается, а ответить на многочисленные вопросы 12 переводчиков – тоже требуется время.

                  Проверка по скриншотам


                  Плюсы:
                  Менее затратно по финансам. Ты присылаешь переводчикам английские инструкции и скриншоты, а так же локализованные скриншоты в том же порядке, что и английские. В итоге, переводчик читает инструкции и сравнивает английские скриншоты с локализованными, и отмечает что и где хорошо бы поправить. Такую работу тоже надо оплачивать по часам, но она занимает гораздо меньше времени чем проверка живого билда.

                  Минусы:
                  К такому типу тестирования надо тщательно подготовиться. Надо не только сделать подробные английские инструкции, но и наснимать такие же скриншоты для каждого языка, а их 12. Приходится потратить порядочно времени.

                  В финале хочется сказать, что конечно же создать простой, удобный и понятный программный продукт, который бы еще и сам себя продавал – мечта любого разработчика. В реальности же все складывается по-другому. Наряду с разработкой вашего продукта, словно подводная часть айсберга, появляются десятки смежных задач, причем считать их незначительными можно до определенной поры. Искренне надеемся, что данная статья была вам интересна. С удовольствием ответим на дополнительные вопросы в комментариях к материалу.

                  З.Ы. И лайфхак на последок!

                  Комментарии (0)

                    Let's block ads! (Why?)