• Phrase.com или как мы автоматизировали флоу локализации
    –1
    Что Phrase, что некоторые другие платформы (не буду их здесь называть), пошли по довольно странному пути абстрагирования от оригинальных форматов файлов в пользу ключей. Этот подход на поверхности выглядит как что-то разумное, однако имеет серьезные недостатки.

    И здесь я хочу сказать большое спасибо за подробное описание своего процесса локализации. Вы очень наглядно показали, что при этом происходит — начинается «управление ключами»: интеграция должна обеспечивать их уникальность, подчистку, вы начинаете переживать, когда ключи не переиспользуются между платформами, когда, по вашим словам, возникают «коллизии», вводите, по сути, жесткие зависимости между iOS- и Android-приложением, привязываетесь к стороннему сервису как к неотъемлемой части инфраструктуры. Сам подход к локализации и API таких систем заставляет вас мыслить о процессе локализации не в совсем эффективном русле.

    Локализация (с точки зрения процесса) и интеграция (с точки зрения разработки и поддержки) может быть гораздо более простой, если брать существующий «родной» подход и API интернационализации для каждой платформы, использовать нативные форматы файлов ресурсов для каждой платформы и переводить их независимо. Эффективное переиспользование переводов — задача TMS/CAT, а не каждого разработчика в отдельности. И я бы посоветовал не переживать по поводу увеличения стоимости переводов: 100% совпадения практически бесплатны, да и стоимость переводов гораздо ниже стоимости дополнительного времени программистов и менеджеров, задействованных в обслуживании этой системы.
  • 20 проектов, 20 языков, срок вчера. Часть 3
    0
    Ну у нас все то же самое — нужно обеспечивать контекстом переводчиков и все такое, но мы пошли от обратного: переводы выгружаются как можно раньше (какие-то с комментариями, какие-то без, тоже в зависимости от формата файлов и от проекта), и переводчики начинают переводить строки с тем контекстом, что есть. А вот когда у них появляются вопросы, мы уже им отвечаем, выборочно добавляем комментарии и скриншоты. Автоматическая выгрузка строк на перевод позволяет еще и как можно раньше обнаруживать проблемы с исходными строками, причем не только силами менеджера по локализации, но и переводчиками, а также позволяет интегрировать переводы раньше и делать QA в CI-сборках продукта (а QA в финальном продукте и подправка переводов, как мне кажется, намного более продуктивен, чем просто перевод, пусть даже и с дополнительными комментариями).

    Поэтому я и подвожу вас размышлению: может быть выгрузка «сразу и как есть» с последующим выборочным добавлением контекста — это не только минус, но и плюс? И если у вас есть возможность реально оценить качество переводов, то это был бы отличный эксперимент (хотя бы на одном проекте каком-то). Вполне может оказаться, что плюсов от такого подхода больше, чем ожидаемых минусов.
  • 20 проектов, 20 языков, срок вчера. Часть 3
    0
    > невычитанные строки или строки без контекста регулярно попадают в Smartcat. Автоматическое назначение в данном случае означало бы для нас дополнительные траты, так как некоторые строки были бы отправлены на перевод дважды: до и после редактуры.

    В моей голове бытует мнение, что стоимость «лишнего» перевода может оказаться дешевле стоимости работы менеджера по локализации; а внедрение в процесс лишней кнопки может приводить к задержкам в работе (переводчики теряют день или больше, ожидая проверки строк) и накладкам (менеджер по локализации забыл что-то оправить в работу и потерял на этом еще день-два). Посему вопрос: не рассматривали ли вы возможность, хотя бы в порядке эксперимента, автоматической отправки на перевод всего и вся с последующими замерами (насколько быстрее проходит перевод, сколько вы реально переплачиваете за повторный перевод с учетом всех совпадений TM, и сколько вы экономите времени менеджера по локализации)?
  • 20 проектов, 20 языков, срок вчера
    0
    Иногда это именно невозможность. При нативной разработке под Android их XML-формат это единственно возможный вариант работы с ресурсами. Нет, можно, конечно, обойти все практики и придумать на этом месте что-то свое, но при этом придется отказываться от кучи удобств связанных с использованием стандартного формата. Т.е. выбор другого формата приносит гораздо больше проблем, чем решает. Ровно та же картина и с другими платформами. Единого формата ресурсов просто нет и быть не может (и не нужно к нему стремиться). Я как раз за то, чтобы не делать культ карго из унификации и позволить инженерам использовать штатные механизмы работы с их проектами.
  • 20 проектов, 20 языков, срок вчера
    +1
    Если вы считаете, что поддержка нескольких общепринятых форматов ресурсов локализации усложняет процесс, то что-то не так с вашим процессом локализации. Это как раз самая незамысловатая часть процесса. А вот перекраивать устоявшиеся практики разработки под платформы (а в некоторых случаях и заставлять инженеров что-то переделывать) — это только наживать проблемы между разработчиками и отделом локализации.

    Я полностью соглашусь с мнением, что интернационализацию и выбор форматов файлов ресурсов лучше продумывать заранее (особенно если платформа разработки позволяет гибкость в этом плане), но и перегибать палку, принуждая всех использовать один и тот же формат, не надо. Да и как я упомянул выше, это просто далеко не всегда возможно.
  • 20 проектов, 20 языков, срок вчера
    0
    Это не всегда возможно: когда приложения/платформы разные, то лучше всего использовать стандартные решения и форматы для каждой платформы (.strings для iOS/macOS, XML для Android, JSON для расширений Chrome и т.д.). А возможность работы с ресурсами разных форматах в системе локализации все равно должна быть, и это уже второстепенная деталь имплементации. Хвост (локализация) точно не должен вилять собакой (инженерами). :)
  • А пусть тесты сами себя и поддерживают
    0
    Согласен, опасность такая есть (как и при любом другом подходе к тестированию, в котором есть человеческий фактор). В моей практике такого пока не случалось; все эталонные данные, которые я сохраняю в файлы, всегда структурированы, поэтому при git diff легко обнаружить такие аномалии. Все изменения шаблонов, например, затрагивают одну и ту же строчку, а в одном эталоне картина изменений другая. Конечно, если какое-то изменение затрагивает очень много эталонных данных (сотни файлов), то шанс что-то пропустить сильно увеличивается. С другой стороны, по самому количеству изменившихся эталонов сразу видно, насколько сильно изменение кода затрагивает поведение системы, и что его надо тестировать тщательнее. То же самое и с code review. Представьте коммит, который включает изменение одного шаблона и коммит, в котором включены десятки изменившихся шаблонов. Понятно, что ко второму внимание всех остальных разработчиков будет более пристальным.
  • А пусть тесты сами себя и поддерживают
    0
    Подход можно использовать для реализации разных типов тестов:
    • При тестировании юнитов на небольшом наборе изолированных и специально подготовленных тестов получается, по сути, обычное табличное юнит-тестирование, с тем лишь отличием, что данные находятся в файлах (со всеми плюсами и минусами хранения данных отдельно от тестов; см. data-driven testing и TableDrivenTests), и что эталонные данные не надо писать руками (но обязательно заверять и относиться к ним так, как если бы вы их писали руками).
    • При тестировании больших кусков кода (типа проверки работы API и возвращаемых им стурктур данных) или даже приложения целиком (запускаем приложение с входными параметрами, получаем что-то на выходе, сравниваем выход) получаем интеграционное тестирование. В этом случае входные и выходные данные могут быть более объемными, чем при юнит-тестировании, так что их хранение во внешних файлах более оправданно, как и автогенерация эталонного вывода с последующей его заверкой.
    • При использовании избыточного количества входных данных теста и незаверенных выходных данных получаем pinning tests (спасибо ApeCoder за правильную терминологию). В этом случае мы тестируем не правильность исходной работы приложения, а лишь фиксируем изменения его поведения (что можно делать как, например, отчет в рамках автоматической сборки билдов).

  • А пусть тесты сами себя и поддерживают
    0
    Если порядок в списке не имеет значения, то список нужно отсортировать, чтобы выход был стабильным. Или (если мы говорим конкретно о Go-реализации), положить ошибки в map[string]string — в этом случае при сериализации в JSON ключи будут идти в сортированном порядке автоматически.
  • А пусть тесты сами себя и поддерживают
    0
    В теории — правильно (иметь минимально достаточный объем тестов, полностью покрывающий все сценарии). На практике могут быть случаи, когда проблема может проявиться только на каком-то особом наборе данных. Так что я считаю, что лучше поймать ошибку так (с помощью избыточных тестов), чем не поймать ее вообще. От падения такого теста уже можно плясать и смотреть, какого максимально независимого и понятного теста не хватает.
  • А пусть тесты сами себя и поддерживают
    0
    Здесь все так же, за исключением того, что не нужно руками сериализовать выходные данные. Достаточно их сгенерировать и заверить.

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

    Работа со слепками данных позволяет автодокументировать работу как отдельных компонентов, так и всей системы, и выявлять такие ошибки, которые на бумажке не обнаружишь. Пример: функция должна выдавать некую структуру с полями A, B и C. На бумажке все хорошо, в тесте все хорошо — мы явно проверяем наличие этих трех полей и их значения. И все совпадает с ТЗ. А посмотрев на слепок данных вдруг оказывается, что с какого-то момента функция начинает еще возвращать и поле D. В ТЗ это не прописано, но такая ошибка может быть совсем не безобидной (приводить к утечке конфиденциальных данных, например).
  • А пусть тесты сами себя и поддерживают
    +1
    Второй раз бизнес-логику в тестах все равно никто не пишет. Все выливается в итоге в подготовку fixtures, запуск куска основного бизнес-кода и в сравнение каких-то параметров выходных данных (при котором легко что-то забыть сравнить). Здесь же сраниваются снэпшоты данных целиком. Да, они генерятся тестами, но после этого их надо проверять, иначе нет смысла все это затевать. Но сам код теста (сравнение снэпшотов данных) как раз по определению отличается от кода бизнес-логики, и чтение готового снэпшота данных, проверенного и отвечающего условиям ТЗ, и дает этот второй независимый путь.
  • А пусть тесты сами себя и поддерживают
    0

    Да, approval tests — это тот же принцип.

  • А пусть тесты сами себя и поддерживают
    0

    Да, очень-очень близко. Спасибо за ссылку!

  • А пусть тесты сами себя и поддерживают
    0

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


    Можно поспорить, что считать хорошим или плохим тестом; с традиционными юнит-тестами я сталкивался как раз с тем, что в юнит-тесте воспроизводился кусок бизнес-логики, создающий объекты и подготавливающий данные, просто потому что это было легко. В итоге тест был плохой, потому что ошибка в бизнес-коде воспроизводилась и в тесте, и тест проходил на ура. Что мне ноавится в подходе с эталонными данными, это то, что код теста там гарантированно другой, и результат всегда нагляден (можно посмотреть, обсудить и прокомментировать в системе code review), и шансов скопипастить багу из основногл кода в тестовый сильно меньше из-за другой природы тестов.

  • А пусть тесты сами себя и поддерживают
    0

    Согласен, ошибку в эталонном файле можно ненароком пропустить. И к тому же данный способ провоцирует на создание большего количества тестов, что приводит к большему количеству эталонных данных (которые все надо тщательно проверять). With great power comes great responsibility...

  • А пусть тесты сами себя и поддерживают
    +1
    Это, разумеется, data driven tests, но только которые сами генерят выходные данные — в этом основная суть подхода.
  • А пусть тесты сами себя и поддерживают
    –1
    По-моему все это очень даже в духе TDD. Тесты никуда не уходят, их только создавать и поддерживать становится легче. Схема такая: пишем сначала тест, формирующий API бизнес-логики, и подготавливаем для него входные данные (тест не проходит); пишем основной код приложения; проверяем код через запуск теста в режиме инициализации и генерацию эталона; rinse & repeat. Можно, конечно, и эталоны генерить руками, только зачем? Главное понимать, какие данные должны быть на выходе (сформулировать для себя эталонный вывод теста), а формально файлик пусть компьютер создает. Ну и коммитить тест и результаты теста вместе с основным бизнес-кодом.
  • Serge — решение для непрерывной локализации от Evernote
    0
    С Transifex мы с ними общаемся, может быть даже попробуем сделать поддержку Transifex в Serge.

    Формально, поддержки непрерывной локализации в самом Transifex нет. Есть их утилита командной строки, которую можно использовать в своих скриптах. Но добавление новых файлов, удаление старых, начальная выгрузка, конфигурирование на стороне веб-интерфейса — все это надо делать руками. И потом, когда это сделано, можно написать свои кастомные скрипты, которые будут делать VCS push/pull и tx push/pull. И опять же потенциально иметь проблемы с мержем на уровне VCS или же писать скрипты для обхода этого. А Serge позволяет однажды настроить процесс и забыть про ручную работу.

  • Serge — решение для непрерывной локализации от Evernote
    0
    Pootle у вас является основным внутренним CAT-инструментом? И именно это и послужило одним из драйверов создания Serge? У меня на работе несколько иная схема, где в ядре находится memoQ.

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

    Я, по правде говоря, и сейчас не знаю других продуктов для непрерывной локализации. Понятно, что в последнее время появилось много CAT-решений, но когда дело касается интеграции процесса внтури компании с этим CAT-решением, обычно требуется интеграция через API (или через клиент командной строки), или же интеграция происходит по принципу «нажми на кнопку, чтобы загрузить новые строки, нажми другую кнопку, чтобы выгрузить переводы». Что у memoQ в этом плане?

    Описанная вами цепочка работает только на локализации интерфейсов? Пробовали ли вы применить Serge для локализации документации?

    Документация у нас вся хранится в виде статей в Zendesk. Есть еще маркетинговые материалы (блог-посты, описания приложений для app store, release notes), которые хранятся в Google Drive. Как для Zendesk, так и для Google Drive мы применяем похожую схему: есть скрипты синхронизации, который забирают контент из внешнего сервиса, генерят локально XML-файлы по одному на документ и выгружают это в систему контроля версий. Дальше все это переводится с помощью Serge+Pootle, а затем эти же скрипты синхронизации выгружают локализованный контент обратно в Zendesk и Google Drive.

    Если у вас документация хранится уже в системе контроля версий в каком-то пригодном к парсингу формате, то ее можно обрабатывать с помощью Segre безо всяких дополнительных ухищрений. Если интересно, пишите в личку, пообщаемся более предметно.
  • Serge — решение для непрерывной локализации от Evernote
    +1
    Хорошие вопросы.

    Образно говоря, translate-toolkit по сравнению с Serge — это Arduino по сравнению с iPhone. Мы активно помогаем разрабатывать Pootle, но рассматриваем его лишь как интерфейс для перевода, не более. Serge+Pootle = полноценная опенсорс-платформа для непрерывного перевода. translate-toolkit мы помогать развивать не намерены. Внутри самого Pootle есть также тенденция уйти от зависимости с translate-toolkit.

    Serge не является конвертером форматов в прямом смысле этого слова. И это сильно больше, чем набор парсеров — рекомендую почитать документацию к управляющим плагинам, например. Снапшоты базы и .po-файлов мы делаем — ничего сложного тут нет. База не такая большая — можно делать бэкап хоть после каждого цикла. Elasticsearch — это TM внутри самого Pootle. Serge позволяет использует свою базу как TM, переиспользует известные переводы (сначала пытается находить 100% матчи внутри файла, потом внутри проекта, затем внутри всей базы).

    Помогать развивать функционал Pootle мы, разумеется, продолжим. Есть много идей для улучшения.
  • Serge — решение для непрерывной локализации от Evernote
    0
    Не все, что удобно в разработке, удобно и быстро для конечных пользователей продукта. Динамическая локализация удобна переводчикам (коих у нас около 30), но имеет свои минусы для инженеров (коих у нас сотня) и конечных пользователей (коих миллионы). Одно дело — перенос своих вычислительных мощностей на AWS. Это прозрачно для пользователей, и скорее всего даже призвано ускорить работу. Другое дело — локализация в рантайме (усложнение кода и процесса).
  • Serge — решение для непрерывной локализации от Evernote
    0
    Поддержка форматов даты и чисел обычно есть в операционной системе — ничего особенного в рамках локализации тут делать обычно не надо. Разработчикам нужно просто следовать правилам, заданным для их платформы.
  • Serge — решение для непрерывной локализации от Evernote
    0
    Сервисы такие есть. Qordoba, например. Но, во-первых, это платно (и цены обычно сильно зависят от размера компании). Во-вторых, ни одна уважающая себя компания не будет ставить свой продукт (рантайм) в зависимое положение от стороннего решения. Это усложняет код, делает его более медленным, это делает локализационное решение нестандартным (чего разработчики не любят), это усложняет тестирование. Наконец, зачем что-то делать в рантайме миллионы раз, когда можно сделать один раз статически?
  • Serge — решение для непрерывной локализации от Evernote
    0
    На уровне Serge есть только возможность протаскивать коммаентарии разработчиков из файлов ресурсов на сервер перевода. Уже на самом сервере переводчики видят эти комментарии, а также скриншоты, которые добавляют менеджеры по локализации. Интерфейс наши инженеры разрабатывают таким образом, чтобы он корректно работал с более длинными строками, а тестирование локализованных сборок позволяет нам выявлять косяки и переводить что-то покороче, когда это возможно, или файлить баги на разработчиков, чтобы они где-то переработали интерфейс.
  • Apple и Alibaba намерены сотрудничать на рынке мобильных платежей
    +3
    «wicked smart» — это «злые и умные»? Вот так и пополняется копилка цитат великих людей, которые они не говорили.
  • Визуальный анализ качества кода
    +1
    Автору, видимо, никогда не приходилось загружать код в область видеопамяти доисторических компьютеров типа БК — там такие картинки естественным путем получались. )

    А вот если взять не получившийся скомпилированный код, а исходник (из него можно больше выцепить информации), проанализировать по каким-то критериям (объем, стиль кода, именование переменных, плотность строк, встречаемость определенных лексических конструкций, комментариев) и на их основе создать какую-то сгенерированную абстракную картинку (а лучше — инфографику), то это было интереснее.
  • Применение диаграммы Парето для анализа причин отставания от графика разработки
    +3
    Похоже у кого-то бага прямо в каждой фитче…
  • История реверс-инжиниринга одного пушистого зверька
    0
    О, и вот тут еще кое-что покрупнее.
  • История реверс-инжиниринга одного пушистого зверька
    0
    Вот тут нашел картинку где видны его запчасти, включая основную плату.
  • История реверс-инжиниринга одного пушистого зверька
    0
    Этот микропроцессор был в одной из старых моделей. Что в новой — неизвестно. К сожалению, игрушка не поддается аккуратному раздербаниванию, обратно ее собрать «как было» не получится, поэтому я ее не разбирал. Вот здесь виден процесс разборки, но микросхем на фото нет.
  • История реверс-инжиниринга одного пушистого зверька
    0
    Если рассматривать эти команды в таких терминах, то SYN+ACK — это вроде как ответ на SYN. А тут обе команды посылает сам Furby.

    Думаю, что пролить свет на этот вопрос может только запись «разговора» двух Furby.
  • История реверс-инжиниринга одного пушистого зверька
    0
    Заказывайте с Амазона с пересылкой (куча разных компаний есть, которые предоставляют виртуальный адрес в США). Если интересно, могу в личку написать, какой я пользовался.

    А по результатам — есть перечень известных команд и их частичное описание (в исходниках проекта на Github).
  • Конкурс на лучшую схему московского метрополитена
    0
    И это реально самая лучшая находка в бирмановской версии.
  • История реверс-инжиниринга одного пушистого зверька
    0
    в тех десяти битах (по 5 в каждой из двух «посылок») и закодирован номер команды, соответствующий номеру WAV-файла?


    Именно так и оказалось, да.
  • История реверс-инжиниринга одного пушистого зверька
    0
    Буду признателен (только в личку, наверно).
  • История реверс-инжиниринга одного пушистого зверька
    +1
    Брал WAV-файлы для последовательно идущих команд (например, 352, 353, 354, 355, ...), по спектрограмме (по «нотам») получал код в четверичной системе и смотрел, как изменяются числа от команды к команде. Закономерность была вида 0, 1, 3, 2 вместо ожидаемой 0, 1, 2, 3, что натолкнуло на мысль, что 3 и 2 надо поменять местами. Картинка и сложилась. Выборочная проверка других случайных команд (все 79 я, разумеется, не проверял) показала, что теория работает.

    Кстати, о контрольных суммах: не проще ли было бы тупым перебором нагенерить вариантов команд, а потом скормить их этому зверю и посмотреть, на что он среагирует?
    Это для каждой команды дает 256 вариантов. Занятие очень утомительное, особенно когда нет гарантии, что даже на один из этих вариантов Furby как-то отреагирует. Сами команды отправляются небыстро, между ними нужны паузы, Furby не все их услышит, если будет в это время что-то делать свое и т.д. Это превратило бы увлекательное занятие в пытку.
  • История реверс-инжиниринга одного пушистого зверька
    0
    Да, забыл спросить: а этот PIN-код как-то влияет на первые два байта команды? У меня ощущение, что PIN-код — это и есть то самый третий байт, который по умолчанию просто равен 1032.
  • История реверс-инжиниринга одного пушистого зверька
    0
    Надо проверить, спасибо за информацию!
  • История реверс-инжиниринга одного пушистого зверька
    +1
    Разумеется — и дешевле (а в Furby много всего напихано для его цены) и спаривать не надо. Для устройств, которые нужно пользовать в непосредственной близости от экрана устройства — самое то!

    Кстати, заметьте, что в формируемом аудио частота звука между «нотами» а также перед и после посылкой меняется плавно. Т.е. все сделано с расчетом на то, чтобы не было резких «биений» в FFT (а значит, как я понимаю, и перепадов давления, которые слышатся как щелчки). Я сначала тоже сделал по простому — просто «ноты» без плавных переходов. И на спектрограмме на границах нот были ужасные красные полосы, а при проигрывании аудио был слышен отчетливый треск. Потом сделал все красиво, почти как на оригинальной картинке, и щелчки прекратились.