...

суббота, 23 мая 2015 г.

[Перевод] Надлежащая оценка производительности для диагностирования и устранения проблем, возникающих при .Net-сериализации

Уважаемые читатели! Представляю вашему вниманию перевод статьи Скота Ханселмана под названием "Proper benchmarking to diagnose and solve a .NET serialization bottleneck".

Для начала, несколько оговорок и комментариев. Во-первых, процесс оценки производительности сложен. Трудно выполнять измерения. Но настоящая проблема состоит в том, что часто мы забываем, ДЛЯ ЧЕГО мы оцениваем производительность чего-либо. Мы берем сложную многомашинную финансовую систему и внезапно чрезвычайно фокусируемся на куске кода, выполняющем сериализацию, который, по нашему убеждению, и ЕСТЬ проблема. «Если я смогу оптимизировать эту сериализацию, написав for-цикл из 10000 итерации и сократив время его выполнения на x миллисекунд, все будет путем».

Во-вторых, это не пост с результатами сравнения производительности. Не ссылайтесь на него и не говорите «видишь! Библиотека X лучше библиотеки Y. Или .Net лучше чем Java!» Вместо этого, рассматривайте его как поучительную историю, а также набор общих рекомендаций. Я попросту использую эту историю, чтобы подчеркнуть следующее:

  • Вы на 100% понимаете, что вы измеряете?
  • Запускали ли вы профайлер типа Visual Studio profiler, ANTS или .dotTrace?
  • Вы учитываете время разогрева? Отбрасываете резко выделяющиеся значения измерений? Ваши результаты статистически значимы?
  • Оптимизированы ли используемые вами библиотеки под ваш сценарий использования? Вы уверены в том, что знаете, каков ваш сценарий использования?

Одна плохая оценка производительности


Один читатель недавно прислал мне e-mail с вопросами по сериализации в .Net. Ребята прочитали один очень старый пост 2009-го года о производительности, который включал графики и диаграммы, и самостоятельно провели какие-то тесты. Они зафиксировали, что время сериализации (десятков тысяч элементов) составляет более 700 миллисекунд, а объемы около 2-х мегабайт. В тесте выполнялась сериализация их типовых структур данных, как на C#, так и на Java, с помощью набора различных библиотек. Среди библиотек был собственный сериализатор их компании, бинарный .Net DataContract, а также JSON.NET. В одном случае сериализация давала малый объем данных (1,8МБ для большой структуры), в другом – работала быстро (94 мс.), но очевидного победителя не было. Читатель был на грани потери рассудка и решил, в каком-то смысле, что .Net не должен использоваться для решения их задачи.

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

Хм… То есть .Net не может сериализовать несколько десятков тысяч структур данных быстро? Я знаю, что может.

Смотрите также: Create benchmarks and results that have value и Responsible benchmarking от @Kellabyte


Я не эксперт, но все же немного поигрался с этим кодом.

Первое: правильно ли мы измеряем?


В тестах использовался DateTime.UtcNow, который не советуют использовать в таких случаях.
startTime = DateTime.UtcNow;
resultData = TestSerialization(foo);
endTime = DateTime.UtcNow;


Не используйте DateTime.Now или DateTime.Utc для измерений там, где нужна какая-либо точность. DateTime не имеет достаточной точности и возвращает время с погрешностью до 30мс.

DateTime представляет дату и время. Это не высокоточный таймер или секундомер.

Как говорит Eric Lippert:

Словом, «сколько времени?» и «как долго это продолжалось?» совершенно разные вопросы; не используйте средство, спроектированное чтобы ответить на один вопрос, для ответа на другой.


И как говорит Raymond Chen:

Точность (precision) – не то же самое, что достоверность (accuracy). Достоверность – это то, насколько вы близки к правильному ответу; точность – насколько высоко разрешение (resolution) данного ответа.


Итак, мы будем использовать Stopwatch там, где нам нужен секундомер. До того как я перевел пример на Stopwatch, я получал значения в миллисекундах вроде 90,106,103,165,94, а после перевода на Stopwatch результаты были 99,94,95,95,94. Колебания значений стали значительно меньше.
Stopwatch sw = new Stopwatch();
sw.Start();
 
// stuff
 
sw.Stop();


Также, вам может потребоваться привязка процесса к одному ядру процессора, если вы пытаетесь получить достоверную оценку производительности. В то время, как это не должно иметь значения и Stopwatch использует Win32 QueryPerformanceCounter (исходный код для Stopwatch в .Net здесь), на старых системах имели место некоторые проблемы, если тест начинался на одном процессоре, а заканчивался на другом.
// One Core
var p = Process.GetCurrentProcess();
p.ProcessorAffinity = (IntPtr)1;


Если вы не используете Stopwatch, поищите простую и хорошо приспособленную для оценки производительности библиотеку.

Второе: считаем результаты


В примере кода, который мне дали, около 10 строк содержали собственно измерения, и 735 строк — «инфраструктуру», отвечающую за сбор и отображение полученных данных. Возможно, вы уже видели подобное? Справедливо сказать, что оценка производительности может потеряться в «инфраструктуре».

Послушайте мой недавний подкаст с Matt Warren на тему "Performance as a Feature" и взгляните на Matt's performance blog, а также убедитесь, что воспользовались книгой Ben Watson под названием "Writing High Performance .NET Code".

Также имейте ввиду, что в настоящее время Matt экспериментирует с созданием компактной инфраструктуры для оценки производительности на GitHub. Эта система довольно многообещающая и могла бы свести процесс выполнения оценки к применению атрибута [Benchmark] непосредственно внутри модульных тестов.

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

Немного более продвинутое средство, на которое стоит взглянуть, это HdrHistogram, библиотека «разработанная для записи гистограмм измеряемых значений в приложениях, чувствительных к времени ожидания и производительности». Она также на GitHub и включает реализации на Java, C, и C#.

И серьезно. Используйте профайлер.

Третье: вы запускали профайлер?


Используйте Visual Studio Profiler, или скачайте триал Redgate ANTS Performance Profiler или JetBrains dotTrace profiler.

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

К слову: есть ли более новые/подходящие/изученные способы решения проблемы?


Это мое мнение, но я думаю, что оно заслуживает внимания и есть цифры, которые это доказывают. Часть кода, выполняющего сериализацию в .Net, довольно стара, написана в 2003 или 2005 году и может не использовать преимущества новых технологий и знаний. К тому же, это довольно гибкий, «подходящий для всех» код, в отличие от очень узкоспециализированного кода.

У людей разные потребности, связанные с сериализацией. Вы не можете сериализовать нечто в XML и ожидать, что результат будет небольшим и компактным. Точно так же вы не можете сериализовать структуру в JSON и ждать, что это будет так же быстро, как при бинарной сериализации.

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

Четвертое: новые .Net-сериализаторы, которые стоит рассмотреть


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

Есть два действительно хороших сериализатора, на которые следует обратить внимание. Это Jil от Kevin Montrose, и protobuf-net от Marc Gravell. Оба являются удивительными, а широта охвата поддерживаемых фреймворков и система построения protobuf-net — просто загляденье. Существуют также другие впечатляющие сериализаторы, входящие в ServiceStack.NET и включающие поддержку не только JSON, но также и JSV и CSV.

Protobuf-net — protocol buffers для .NET


Protocol buffers – это формат описания структур данных от Google, а protobuf-net – высокопроизводительная реализация protocol buffers под .NET. Представьте, что это XML, только компактнее и быстрее. Кроме того, с возможностью кросс-языковой сериализации. Вот, что указано на их сайте:

Protocol buffers имеют множество преимуществ при сериализации структурированных данных, по сравнению с XML. Они:

  • проще
  • от 3 до 10 раз меньше
  • от 20 до 100 раз быстрее
  • более однозначны
  • генерируют классы доступа к данным (data access classes), которые проще использовать в программном коде

Добавить это было просто. Существует много способов декорировать ваши структуры данных, но по существу:
var r = ProtoBuf.Serializer.Deserialize<List<DataItem>>(memInStream);


Цифры, которые я получил с protobuf-net были исключительными, и в данном случае данные паковались плотно и быстро, заняв только 49мс.

JIL — Json-сериализатор для .NET, использующий Sigil


Jil – это Json-сериализатор, менее гибкий, чем Json.net, но эта маленькая жертва приносится им во имя скорости. Вот, что они говорят:

Гибкость и «клевые фичи» явным образом игнорируются в погоне за скоростью

Также стоит отметить, что некоторые сериализаторы работают со строкой в памяти, в то время как другие, например Json.NET и DataContractSerializer, работают с потоком (stream). Это означает, что вам стоит принять во внимание размер того, что вы собираетесь сериализовать, когда выбираете библиотеку.

Jil впечатляет многим, но особенно тем, что он динамически эмитит custom-сериализатор (как это делали когда-то делали XmlSerializer-ы).

Jil крайне прост в использовании. Он просто работает. Я добавил его в пример и он выполнил сериализацию за 84мс.

result = Jil.JSON.Deserialize<Foo>(jsonData);

Заключение: со сравнением производительности все не так просто


Что вы измеряете? Для чего вы это измеряете? Соответствуют ли ваши методы вашим сценариям использования? Вы сериализуете один большой объект или тысячи маленьких?

James Newton-King донес до меня одну прекрасную мысль:

"[Имеет место] мета-проблема, связанная со сравнением производительности. Микро-оптимизация и забота о производительности тогда, когда это не имеет значения, это то, чем грешат многие разработчики. Документация, производительность разработчиков и гибкость важнее, чем сотая доля миллисекунды."


James указал на старую (но недавно исправленную) ошибку ASP.NET в Twitter. Это важная ошибка, влияющая на производительность, но она, тем не менее, меркнет в свете того времени, которое тратится на передачу данных по сети.

Эта ошибка подтверждает мысль о том, что множество разработчиков заботятся о производительности тогда, когда это не имеет значения
James Newton-King (@JamesNK) 13 Февраля 2015г.


Спасибо Marc Gravell и James Newton-King за их помощь при подготовке этого поста.

Оригинал статьи доступен по этой ссылке

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Конечный автомат на bash

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

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

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

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

if [[ $STEP == 'step3' || $STEP == 'step4'  || … || $STEP == 'step10' ]]

на каждом шаге переменной $STEP присваивается значение следующего шага:

if [[ $STEP == 'step3' ]]
then
    # Полезные действия. Возможно выход.
    STEP='step4'
fi
if [[ $STEP == 'step4' ]]
then
    # Полезные действия. Возможно выход.
    STEP='step5'
fi

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

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

if [[ $STEP == 'step3' ]]
then
    # Полезные действия
    if [[ условие ]]
    then
        STEP='step4'
    else
        STEP='step5'
fi

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

Однако написанный код не позволял делать одну важную вещь — совершать произвольный переход. В нем последовательность переходов жестка зашита последовательностью шагов в коде. Шаги можно только пропускать. Осознав проблему код был переписан:

function step1 {
    # Действия выполняемые на шаге 1
}

function step2 {
    # Действия выполняемые на шаге 1
}
…

while [[ -z $EXIT ]]
do
    case $STEP in
    step1)
        step1
        if [[ условие ]]
        then
            STEP='step2'
        else
            EXIT=1
        fi
    ;;
    step2)
        step2
        if [[ условие ]]
        then
            STEP='step3'
        else
            STEP='step1'
        fi
    ;;
    ...
    step10)
        step10
        if [[ условие ]]
        then
            STEP='step6'
        else
            STEP='step9'
        fi
    esac        
done

В результате получили:

  • Полную изоляцию состояний. Каждое состояние — отдельная функция.
  • Свободу в переходах между состояниями независимо от последовательности их описания в коде.

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

Поскольку мне была возможность остановить скрипт и продолжить его работу через некоторое время, я написал функцию сохранения состояния:
function saveState {
    echo -e «STEP='$STEP'\n» > state
}

Вызов функции добавил в конец скрипта, а в начало загрузку состояния: source state.

Простой скрипт для экспериментов:

#!/bin/bash

STEP='step2' # Начальное состояние

function step1 {
    echo 'step 1'
}

function step2 {
    echo 'step 2'
}

# Сохранить состояние
function saveState {
    # Таким образом можно сохранить значение любых переменных
    echo -e "STEP='$STEP'\n" > state;
}

# Главный цикл
function main {
   # Сигналом к завершению служит наличие значения у переменной EXIT     
    while [[ -z $EXIT ]]
    do
        case "$STEP" in
        step1)
            step1
            EXIT=1
        ;;
       step2)
           step2
           STEP='step1'
       ;;
       esac
   done
}

# Если существует файл state прочитать сохраненные в нем значения (на самом деле выполнить)
if [ -f state ]
then
    source 'state'
fi
main # Главный цикл
saveState # Перед завершением сохранить состояние.

После первого вызова он выведет:

step2
step1


После второго:

test1

Сбросить состояние можно удалив файл state в директории скрипта.

Несколько советов

Обратите внимание на то, что bash ОЧЕНЬ чувствителен к пробелам и их отсутствию. Также в нем необычное понимание числовых значений как истина и лож, 0 — истина (связано с тем, что программы возвращают 0 в случае успешного завершения, и отличное от нуля значение в случае ошибки). Для отладки скрипта полезно запускать его командой bash -x .

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Конвертация записей разговоров в mp3 — Elastix 2.5 (FreePBX 2.11)


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

В старых версиях файлы записей хранились по умолчанию в одной папке, создавая тем самым проблемы при их большом количестве. В Elastix 2.5 перешли на FreeBPX 2.11, а там, как известно, записи телефонных разговоров раскладываются по папкам на каждый день.
Соответственно изменились (добавились) переменные для использования со скриптом конвертации записей после звонка.

Причем, в старых версиях, добавить параметр “Run after record” можно было прямо через панель управления Elastix, в разделе “General Settings”. В новой версии, для того чтобы добавить это параметр (кстати, параметр тоже поменял название — “Post Call Recording Script”), нужно воспользоваться панелью управления FreePBX.

Итак, в чем суть: мы будем конвертировать файл после разговора в формат mp3 с помощью lame, потом, с помощью ffmpeg мы добавим заголовок к файлу записи и сменим расширение обратно на .wav. В итоге все останется для самой системы неизменным, однако существенно уменьшится размер хранимых файлов, по моей оценке в 7-10 раз.


В первую очередь необходимо установить в систему пакеты ffрmpeg и lame:

# rpm -Uhv http://ift.tt/14qJ9cA
# yum --disablerepo=commercial-addons install ffmpeg lame

Параметр --disablerepo=commercial-addons необходим потому что, в репозитории commercial-addons присутствует пакет ffmpeg, который нам не подходит.

Создаем папку для нашего скрипта:

# mkdir -p /etc/asterisk/scripts; chown asterisk. /etc/asterisk/scripts

Забираем скрипт с github:

# wget http://ift.tt/1cSbsrV -O /etc/asterisk/scripts/mixmon-mp3-2.sh

Устанавливаем права на файл

# chown asterisk. /etc/asterisk/scripts/mixmon-mp3-2.sh
# chmod a+x /etc/asterisk/scripts/mixmon-mp3-2.sh

Сам репозиторий на github.

Выполняем команду visudo и добавляем в конец файла:

asterisk ALL = NOPASSWD: /bin/nice
asterisk ALL = NOPASSWD: /usr/bin/ionice
asterisk ALL = NOPASSWD: /bin/chmod
asterisk ALL = NOPASSWD: /bin/chown
asterisk ALL = NOPASSWD: /bin/rm
asterisk ALL = NOPASSWD: /bin/touch

Вот теперь, мы выполнили все необходимые действия в консоли, и можем спокойно переходить к панели управления FreePBX:
Идем в раздел “Settings -> Advanced Settings” и включаем 2 параметра (Display Readonly Settings, Override Readonly Settings)

Применяем изменения. У нас теперь появилась возможность редактировать дополнительные параметры.
В параметр “Post Call Recording Script” вставляем значение:

/etc/asterisk/scripts/mixmon-mp3-2.sh ^{YEAR} ^{MONTH} ^{DAY} ^{CALLFILENAME} ^{MIXMON_FORMAT} ^{MIXMON_DIR}


В параметр “Override Call Recording Location” вставляем значение:
/var/spool/asterisk/monitor/

Применяем все изменения.
Всё, теперь все записи телефонных разговоров, после разговора, будут конвертированы в формат mp3, с сохранением расширения .wav.

Для старых версий файл скрипта mixmon-mp3.sh, а парамерт “Run after record”:

/etc/asterisk/scripts/mixmon-mp3.sh ^{MIXMON_DIR} ^{CALLFILENAME} ^{MIXMON_FORMAT}

И еще, перед тем как Вы включите это всё, несомненно вы захотите конвертировать уже имеющиеся у вас записи телефонных разговоров. Для этого, файл скрипта conv.sh и запускаем команду из консоли:

find /var/spool/asterisk/monitor/ -name '*.wav' -exec ./conv.sh {} \;


Процесс не быстрый.

Теперь, когда вы будете прослушивать файлы записей, формат будет mp3 — обратите внимание на картинку:

Что касается логов:
По умолчанию, Elastix пишет полные логи, и складывает CDR аж в три места (mysql, sqlite и файл csv):
/etc/asterisk/logger.conf и ему сопутствуюшие, оставьте только:
console => notice,warning,error
/etc/asterisk/cdr.conf и ему сопутствуюшие, оставьте только запись в mysql.

Вот и всё!

Удачи в настройках.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

пятница, 22 мая 2015 г.

Мой опыт внедрения Apache Cassandra

Как и большинство NoSQL-решений, C* подвержена одной крайне неприятной эпидемии: она является отличным инструментом для узкого класса задач, но позиционируется евангелистами как очередная серебряная пуля по хранению данных. В этой статье я расскажу о своём опыте внедрения C* в (сравнительно) нагруженный проект веб-аналитики. Она будет полезна всем, кто стоит перед выбором масштабируемого хранилища данных, и развенчает мифы и заблуждения об этом инструменте.

Для начала о позитивных моментах. Как я и сказал раньше, с основными своими задачами C* справляется на Ура. Она была создана для быстрой записи, масштабируемости и отказоустойчивости, и в этом она, наверное, лучшая: я ещё не встречал более простого управления кластером, и за всё это время она меня не подвела ни разу. Однако, самая большая проблема C* в том, что её область применения гораздо уже, чем может показаться из документации. И далее я по пунктам расскажу почему.

CQL — это не SQL


Честно говоря, я вообще не понимаю, зачем разработчики C* решили создать CQL. Он запутывает и дезориентирует, создаёт ложные впечатления о специфике работы C*. Вот вам несколько фактов:
  1. Главное заблуждение, в которое вводит CQL всех новичков, — это иллюзии о том, что вы сможете делать какие-то выборки. Это не так. С* — это key-value хранилище. Вы не сможете получить подмножество строк в таблице. Либо одну (по ключу), либо все. Для обхода этого ограничения в C* есть «wide rows» — возможность писать в строку любые колонки (независимость от схемы, до 2 млрд уникальных колонок в строке). Но и это спасает только при особом подходе к планированию модели данных.
  2. CQL вводит понятия partition key и cluster key внутри PRIMARY KEY. Ещё одно крупное заблуждение в принципе работы этой БД. На самом деле строка в C* определяется только через partition-часть. Все «записи», отличающиеся по cluster key, будут просто укладываться друг за другом внутри одной и той же строки.
  3. Нет никакого compound partition key. Проще всего понять поведение compound key — это представить, что значения полей ключа конкатенируются перед сохранением. И строку можно получить только по полному значению ключа (как в redis, к примеру).
  4. INSERT и UPDATE в C* — это одно и то же. Отныне и во веки веков.
  5. Коллекции в CQL — это лишь синтаксический сахар, и записи в них хранятся в отдельных колонках.
  6. Вторичные индексы — тоже лишь синтаксический сахар. C* создаёт новое семейство ключей (таблицу) для каждого вторичного индекса и дублирует туда записи.

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

Особенности проектирования данных


Главный принцип при проектировании данных в C* — «SELECT-driven model». Вы проектируете данные так, чтобы вы их смогли потом получить с помощью SELECT. В рамках key-value wide-row хранилища это подразумевает очень сильную денормализацию. Вы не просто денормализуете данные, как вы раньше привыкли это делать в реляционных БД, вы фактически создаёте отдельную таблицу под каждый запрос. И во многих проектах (там, где очень много данных по объёму) это даёт либо огромный overhead во время map/reduce и агрегации, либо огромный overhead по объёму хранимых данных.

И да, вам сразу стоит быть готовым к тому, что без распределённого агрегирования (Hadoop, Spark, Hive и т.д.) эта БД бесполезна. Разработчики обещают в следующей версии операторы для агрегации данных в CQL, но можете особо не надеяться на них. По архитектуре этой БД ясно, что они будут работать только внутри одной строки.

Каунтеры


Отвожу этому типу данных в этой БД свой собственный раздел, и вот почему: изначально, когда я начал внедрять C* в свой проект, я очень обрадовался: для веб-аналитики очень круто иметь атомарные каунтеры, они очень сильно упрощают систему. Но потом я понял простую истину: никогда, слышите? НИКОГДА не используйте каунтеры в C* (по крайней мере в версии до 2.1.* включительно). Дело в том, что этот тип данных противоречит всей идеологии этой БД, и из-за этого у него огромное количество проблем. Если вы спросите у любого специалиста по C* про каунтеры, он в ответ начнёт лишь злобно хихикать.

Короче:

  1. Вы не можете класть в строку с каунтерами никаких других значений, кроме каунтеров
  2. Вы не можете класть каунтеры в коллекции (по причине выше)
  3. Вы не можете сделать каунтер cluster и partition key (по причине выше), сортировать по ним и ставить на них вторичные индексы, само собой, тоже
  4. Каунтеры имеют проблемы с репликацией (редко, но метко)
  5. Если вы удалите каунтер, то вы ещё долго не сможете создать его заново

Суть расхождения идеологии каунтеров и самой БД в том, что все операции в C* — идемпотентны (т.е. повторное применении операции не изменяет результата). Именно это даёт безотказную архитектуру при падении узлов, датацентров, проблемах со связью и т.п. Каунтеры же нарушают этот принцип, и внутри сделаны через «light transactions» — сначала считать значение, потом увеличить его. И это вызывает много проблем. В общем, если вам нужны счётчики, лучше вопользуйтесь Redis-прослойкой, а в С* уже складывайте окончательное значение.

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

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Анимация персонажей в Blender 3D — это просто

Мир open source не стоит на месте и постоянно развивается. Про Blender 3D написано уже много статей, но помимо Blender, существует еще много полезных и бесплатных программ. Одна из них, это MakeHuman. На Хабре упоминания о ней имеются, но какой либо информации по ней нет. Предлагаю вам заглянуть под кат и посмотреть, что анимация персонажей в связке MakeHuman+Blender3D, это действительно просто. Осторожно, много картинок.


Т.к. сегодняшняя тема связана именно с созданием анимации, то начнем с небольшой подготовки. Скачаем MakeHuman. На сегодняшний день, актуальная версия 1.0.2. Распакуем архив в любую папку. Далее, скачиваем Blender tools с этой же страницы и распаковываем содержимое архива. В данном архиве, содержится четыре папки: mhx_importer, makewalk, maketarget, makeclothes. Все эти папки необходимо скопировать туда, где Blender сможет их найти. В зависимости от операционной системы, эти папки следующие:
  • Windows 7,8: C:\Users\%username%\AppData\Roaming\Blender Foundation\Blender\2.6x\scripts\addons
  • Windows XP: C:\Documents and Settings\%username%\Application Data\Blender Foundation\Blender\2.6x\scripts\addons
  • Vista: C:\Program Files\Blender Foundation\Blender\%blenderversion%\scripts\addons (this is valid at least for blender 2.69)
  • Linux: /home/$user/.blender/$version/scripts/addons

Запустим Blender и перейдем в настройки (Ctrl+Alt+U).
В дополнениях, у вас должен появиться пункт MakeHuman, при выборе которого вы увидите три дополнения, которые необходимо активировать проставив галочки.

Так же, необходимо активировать дополнение Import-Export Make Human:

И Rigify:

Последнее, что необходимо сделать в настройках, это поставить галочку возле Auto Run Python Scripts (необходимо для работы скрипта импорта).

Сохраняем настройки нажав Save User Settings.

Моделирование персонажа


Запустим makehuman.exe:

Сразу скажу, что русский язык включается в настройках.

MakeHuman, это генератор персонажей мужского и женского пола. По пиктограммам и надписям, думаю понятно, какой ползунок за какую часть человеческого тела отвечает.
Во вкладке «Моделирование» персонажа можно состарить, изменить цвет кожи, сделать ему длинные руки, ноги и т.д.
Во вкладке «Геометрии» персонажа можно одеть, добавить ему волосы, зубы, брови, веки и язык и другие необходимые органы (если требуется).

Для примера, я сделал вот такого симпатичного молодого человека.

Теперь, необходимо добавить ему кости для анимации.
Переходим во вкладку Поза-Анимировать и выбираем любые понравившееся кости. Я выбрал кости «Basic».

Далее, экспортируем нашего персонажа в формат понятный Blender`у. Файл->Экспорт, выбираем всё как на скриншоте:

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


В Blender, удаляем всё со сцены и идем в меню File-Import->MakeHuman:

Ищем сохраненный ранее файл и выбираем его.

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

Blender поддерживает формат анимации bhv. Данную анимацию, в основном, получают с помощью Motion Capture. В интернете много файлов с готовой анимацией. Мы возьмем анимацию отсюда . Скачиваем архив Zip file for BVH directories 01-09 (45 MB). и распаковываем.
Убеждаемся, что в Blender выбран наш персонаж и в так называемом «T» окне, выбираем вкладку Misc и нажимаем кнопку Load And Retarget.

В открывшемся окне выбора файла, выбираем любой понравившийся нам файл с анимацией bhv, который мы скачали ранее.

И теперь можно насладиться нашей анимацией, нажав кнопку Play.


1. MakeHuman при экспорте сохраняет файл персонажа в файл с расширением mhx и рядом создает папку textures которой лежат текстуры глаз, кожи и т.д. Вы всегда можете дорисовать что-то своё. Например татуировки или шрамы. UV развертку он тоже создает самостоятельно.

2. После того как вы накопите у себя много файлов с анимациями bhv, становиться трудно ориентироваться в них всех. Естественно, вам хочется иметь какой-то предпросмоторщик. И он есть. Называется bvhacker, является бесплатной и open source программой и живет здесь. Так же, с помощью него можно исправлять и корректировать анимацию.

На этом на сегодня всё, надеюсь информация будет кому-то полезной.

В следующей статье расскажу о том, как создать анимацию, используя камеру и motion capture в blender.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Пост усиленного ретро


Пятничный пост, посвященный тому как и о чем люди думали несколько (десять? двадцать?) лет назад, касательно веб-разработки.

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

… Вот несколько примеров вещей, которые вы не сможете сделать хорошо в веб-приложении:

  • Создать быструю программу для рисования
  • Разработать проверку правописания в реальном времени с волнистым красным подчеркиванием (а можем ли мы сейчас??)
  • Предупредить пользователя о том, что они потеряют всю свою работу, если нажмут крестик на окне браузера
  • Обновить небольшую часть представления (отображения), основанного на изменении со стороны пользователя, без пересылки данных на сервер и обратно
  • Создать быстрый, клавиатурно-направленный интерфейс не требующий использования мыши
  • Позволить людям работать без постоянного соединения с интернетом
Оригинал
Here are a few examples of things you can't really do well in a web application:
  1. Create a fast drawing program
  2. Build a real-time spell checker with wavy red underlines
  3. Warn users that they are going to lose their work if they hit the close box of the browser
  4. Update a small part of the display based on a change that the user makes without a full roundtrip to the server
  5. Create a fast keyboard-driven interface that doesn't require the mouse
  6. Let people continue working when they are not connected to the Internet

А вот выдержка из стайлгайда по HTML от Стефаноса Пепероглу

А вы видели нашу главную страницу в новых браузерах? Вам понравилась разметка? Думаете это таблица? Нет, это разметка, все верно, но она сделана при помощи CSS!

Оригинал

Have you seen our front page with a new browser? Do you like the layout? Think that's a table? Nope. It's layout, alright, but it's done with CSS.


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

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

Просто посмотрите, стадия воплощения отделена от стадии последующей поддержки. Это просто шедеврально!

А вот фрагмент обзора CSS (да-да, самой первой версии)

… Взглянем на пример использования CSS, предположим вы хотите, чтобы все h1 теги использовали шрифт Verdana, высотой в десять пунктов. Вместо того, чтобы обозначать это явно, вы можете просто использовать CSS:

H1 {font-family: Verdana; font-size: 10pt;}


Использование CSS дает даже больше, CSS способен распределить контент страницы до самого последнего пикселя. Преподнося вам полный контроль над образом вашей страницы, он дает вам и полный контроль над текстом. Фактически, CSS заменит некоторые старые HTML теги в будущих версиях браузеров…
Оригинал
Let's take a quick example at a usage of CSS. Suppose you want all your H1 tags to have a 10-point Verdana font. Instead of defining every all your H1 tags in your page with these preferences, you can just use CSS:
H1 {font-family: Verdana; font-size: 10pt;)


CSS usage goes far beyond that. CSS is capable of spacing out the content of a page down to the very last pixel… it can do the same when sizing text, giving you complete control over the look and feel of your page. In fact, CSS will replace some older HTML tags in future browser versions.

Продолжение той же статьи обещает нам, что JavaScript будет использоваться и на бэкенде. И это 2002 год.А следующую выдержку можно привести в качестве ответа на вчерашний пост о HTML6:

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

Оригинал

Conclusions. HTML is proving insufficient by itself to develop the myriad Web-based applications envisioned. As extended by server and client programs, the task is feasible, yet awkward and sub-optimal in terms of performance and safety.


Всем хороших выходных, и помните о главном — мир всегда уже никогда не будет прежним!

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Не мамонт ли Вы? (пятничный тест; который ложь, да в ней намек)

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

Как грибы растут стандарты, фреймворки, развивается и становится всё слаще синтаксис, растут разнообразные инструменты.

И это здорово!

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

Попробуйте пройти несложный тест и определить — не мамонт ли Вы в мире PHP? Не грозит ли Вам, как специалисту, вымирание в ближайшее время?

Тест, разумеется, пятничный и шуточный. Но в нём всё-таки есть доля истины.

Вы пишете на современных версиях языка


Основная версия 5.6? Отлично, начислите себе 10 баллов. Уже собирали PHP 7 и тестировали свой код под ним? Прекрасно, добавьте еще 5 баллов.

До сих пор пишете «array()»? Пугаетесь слова «трейт»? Ничего не знаете о генераторах? Используете md5 для хэширования паролей? Пора просыпаться, версия 5.4 вышла три года назад! Где вы были эти три года? Спали в хрустальном гробу? Вот только не нужно ничего говорить про тонны legacy-кода и про хостинги. Первая проблема это не проблема кода, а проблема вашей лени, а вторая вообще не существует в условиях, когда можно взять свой сервер всего за 250 рублей в месяц и организовать свой собственный хостинг.

Вы используете современные системы контроля версий


Что, вы не используете VCS в повседневной работе? Закройте эту страницу. Я серьёзно — вам не нужно дальше проходить тест, вам нужно немедленно позвонить ближайшему франчайзи «1С» и устроиться к нему внештатным разработчиком на побегушках.

Если же вы не мыслите своей работы без Git (или Hg, например) — начисляйте себе 20 баллов

Вы правильно используете современные системы контроля версий


Начислите себе по 5 баллов за каждое утверждение, которое соответствует вам и вашему стилю работы:
(слово «git» можно заменять на другую VCS)
  • Всё должно быть в git-е
  • Всё — это значит всё! И даже конфиги приложения
  • Crontab должен быть в git-e
  • Инъекции в конфиги php или веб-сервера берутся откуда? Правильно, из вашего репозитория!
  • Все изменения в структуре и системных данных в БД — только через Git, используем миграции или иной механизм
  • Ну сколько раз повторять — ВСЁ ДОЛЖНО БЫТЬ В GIT-Е!

Вы используете современные системы контроля версий в соответствии с чётким workflow


Если вы работаете по git flow — сразу добавьте себе 25 баллов, пожалуйста. В противном случае добавляйте по 5 баллов за каждое утверждение, которое относится к вам:
  • Всегда есть стабильная ветка, чьё состояние точно соответствует состоянию продакшна
  • Каждой задаче — своя ветка
  • Исключений из этого правила не бывает
  • Ветки могут быть разных типов, в зависимости от типа задачи
  • Любая ветка рано или поздно будет влита в стабильную (тем или иным путём) и/или удалена

Вы не вносите изменения в БД руками, для этого есть миграции, которые можно накатывать и откатывать


Неважно какой фреймворк вы используете, простейший механизм миграций в состоянии написать даже Junior за пару часов. Согласны? Так и делаете? Никогда не лазаете в БД на продакшн, чтобы добавить поле или индекс? Поздравляю, заберите 10 баллов.

Хотите поспорить? Знаете, что такое ловчая яма? Вы — мамонт, вы сидите в этой яме и пытаетесь спорить с охотниками, раздумывающими, как вас оттуда вытащить — целиком или всё-таки предварительно порубив на куски. Удачи!

Вы используете сценарии сборки


Дружите с phing? Или знакомы с Capistrano? А может быть используете Ant? 15 баллов в студию!
И да, вы же помните — сценарии сборки у вас лежат где, где? Правильно, в доме, где резной палисад в git-е!

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

Автоматический деплой


Teamcity? Или Jenkins? Или, может быть, Bamboo? Поздравляю, вы на шаг ближе к билету на Ноев ковчег и заодно получаете бонус — 10 баллов. Первый раз слышите эти слова? Или считаете себя умнее всех и написали свой велосипед для выкладки релизов? У меня для вас плохие новости. Тут одно из двух — или вымирать, или эволюционировать, — выбирайте!

PHPStorm?


  • Да? 10 баллов
  • Vi(m)? 5 баллов. Просто из уважения к динозаврам. Они переживут всех мамонтов, поверьте.
  • Что-то другое? 0 баллов

Фреймворки


Zend? Symfony? Laravel? Yii, прости господи? Прекрасно. Добавьте себе 20 баллов, если для вас это не пустые слова, а каждодневная работа.

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

Плюс еще 5, если вас хотя бы однажды посещала мысль «До чего же криво в этом фреймворке реализовано X, я бы переделал» или плюс 15 баллов, если вы взяли и переделали.

Спрашиваете, зачем нужны PHP-фреймворки? Хотите узнать, не стоит ли изучить CodeIgniter? Не понимаете, зачем управлять зависимостями в коде, ведь можно просто скачать к себе в проект нужную библиотеку? ОК, как только построят машину времени, я отправлю вас на 15 лет назад, где вы сможете в полной мере блеснуть своими талантами, а пока можете прибегнуть к криоконсервации, ведь вам всё равно будет нечем заняться в ближайшие годы.

Вы — немного DBA


Вы знаете, что на MySQL мир реляционных баз данных не заканчивается. Вы хотя бы раз в жизни выбирали сервер БД исходя из бизнес-требований к будущему приложению (и остановились на Postgres, не так ли?). Вы отчетливо понимаете, что в общем случае каждый JOIN — это вложенный цикл, прекрасно знаете, что правильные индексы и некривые запросы дадут для производительности гораздо больше, чем шардинг и балансировка нагрузки, не считаете NoSQL панацеей и смеетесь над идеей применять MongoDB в качестве основного хранилища реляционных по своей природе данных. А еще вы без фанатизма используете ORM тогда, когда это нужно, «голые» запросы, когда это оправдано и не боитесь переносить логику во внешние ключи, триггеры и процедуры.

Да? Возьмите с полки 20 баллов, вы готовы к будущему. Остальным — всё тот же выбор. Не задерживаем очередь, выбираем — вымирать или развиваться? Следующий!


200 баллов


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

От 100 до 200 баллов


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

Менее 100 баллов


Много вкусного мяса! «Мням-мням-мням» — слышите, как щелкают челюсти ваших конкурентов? Сожрут-с, однако.

P.S. Не воспринимайте тест всерьёз, всё-таки пятница!

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

[Перевод] Оптическая регулировка

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

Такой подход казался мне логичным, но он оказался неверным.

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

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

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



Выравнивание + визуальный вес


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

Треугольник внутри иконки выровнен по центру круга, так? Не правильно. Если нарисовать прямоугольник поверх треугольника, то мы увидем, что он не находится по центру.


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

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

Чтобы решить проблему, нам нужно вручную пододвинуть треугольник.



Цвет


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

У иконки и текста слева один и тот же hex код, а у иконки и текста справа — разный.

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



Масштаб


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


Обе фигуры слева 120 × 120 пикселей, поэтому круг кажется меньше. Круг справа 126 × 126 пикселей для компенсации большей площади квадрата

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


Обратите внимание, как верх и низ букв шрифта Didot скачет относительно базовой линии



Заглавные буквы


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


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



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

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

От переводчика. Со всеми пожеланиями и замечаниями по поводу перевода прошу обращаться ко мне в личку. Спасибо!

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Анализ изображений и видео. Обнаружение текста на изображениях

сегодня в 17:58

Сегодня мы публикуем последнюю лекцию курса «Анализ изображений и видео», прочитанного Натальей Васильевой — старшим научным сотрудником HP Labs и руководителем HP Labs Russia. Наталья Сергеевна читала курс, посвящённый анализу изображений, в петербургском Computer Science Center, который создан по совместной инициативе Школы анализа данных Яндекса, JetBrains и CS клуба.

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

  1. Введение в курс «Анализ изображений и видео»;
  2. Основы пространственной и частотной обработки изображений;
  3. Морфологическая обработка изображений;
  4. Построение признаков и сравнение изображений: глобальные признаки;
  5. Построение признаков и сравнение изображений: локальные признаки;
  6. Поиск по подобию. Поиск нечетких дубликатов;
  7. Классификация изображений и распознавание объектов;
  8. Анализ изображений и видео. Сегментация изображений.

Под катом вы найдете план новой лекции и слайды.

Компоненты системы извлечения текста:

  • Приложения.

Обнаружение текста – газеты, журналы, книги:
  • Печатные документы
  • Projection profiles and XY-cuts
  • Методы «снизу-вверх»
  • Преобразование Хафа(Hough transform)

Обнаружение текста – произвольные изображения:
  • Фотографии
  • Stroke Width Transform (SWT)
  • Обнаружение текста при помощи SWT
  • Вычисление SWT
  • Обнаружение текста с помощью SWT
  • Комбинированные методы
  • ICDAR (2003, 2005, 2009, 2011)
  • Text detection with unsupervised feature learning

Обнаружение текста – чертежи и графики:
  • Графики и диаграммы
  • Экспериментальная оценка
  • Screenshots
  • Script dependency.

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

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Итоги конкурса проектов с API Aviasales

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



Оценивая работы, мы обращали внимание на следующие критерии:

  • оригинальность идеи
  • техническая реализация (степень готовности прототипа и его работоспособность)
  • коммерческая составляющая проекта
  • внешний вид и юзабилити

И с радостью объявляем победителя – им стал проект privet.travel под руководством Вадима Мерзликина – он получает 150 000 рублей на развитие и продвижение.

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

Изначально мы собирались не делать разницы между вебом и мобайлом и оценивать все проекты вместе, но в ходе голосования всё-таки решили учредить ещё дополнительный приз для лучшего мобильного проекта – им стало приложение Traveler Today Ивана Рыговского, который получит 50 000 рублей. Мы считаем, что у проекта есть неплохой потенциал.

image В описаниях работ других финалистов было несколько интересных идей, но к сожалению, не все проекты доработаны до той стадии, когда мы можем посмотреть и протестировать заявленные в презентации фичи. Надеемся, вы все (включая победителя) продолжите разработку и через пару месяцев покажете уже куда более готовые проекты, мы же, как и обещали, всегда поможем советом и направим проект в правильное русло.
А чтобы работалось веселее, мы даем всем участникам конкурса повышенную ставку – 70%, на первые 3 месяца. Как только решите, что проект готов, пишите в саппорт и мы её включим.

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

Не бросайте начатое и ещё раз спасибо за участие!

Наши предыдущие посты:

» Aviasales со вкусом Airbnb
» Как Aviasales на Material Design переходил
» А у нас есть SDK, а у вас?

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

[Перевод] Новые возможности для разработчиков приложений в Search Console

Всем привет, а тем, кто читает нас в приложении Хабра, привет утроенный! Мы уже рассказывали вам, как изменить файл AndroidManifest.xml и добавить нужную разметку, чтобы контент приложения индексировался и отображался в наших результатах поиска. Рассказывали и как это отразилось на результатах мобильного поиска.

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

Search Console, анализ поисковых запросов для приложений

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

Добавьте свое приложение в Search Console


Получить нашу статистику могут только подтверждённые владельцы приложений. Для начала работы с приложениями в Search Console вам потребуется выполнить всего два простых шага:
  1. Войти в аккаунт Google Play, имеющий доступ к управлению данным приложением;
  2. Открыть Search Console и ввести название приложения, например: http://ift.tt/1K96MsI.

Добавить приложение в Search Console

Если у вас нет доступа к приложению в этом сервисе — не беда, попросите владельца подтвердить приложение в Search Console и добавить вас в свой аккаунт.

Свяжите свой сайт с приложением


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

Отслеживайте положение контента в результатах поиска


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

Подробный отчёт с фильтрами в анализе поисковых запросов

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

Убедитесь, что Google правильно обрабатывает ваше приложение


Теоретически, всё должно работать «из коробки»: вы загружаете приложение, оно анализируется нашей платформой, вы получаете результат. Однако, если поисковой робот обнаружит ошибки на страницах приложения, мы не сможем показывать ссылки на контент в результатах поиска. Чтобы исправить данное недоразумение мы создали «отчёт об ошибках сканирования», благодаря которому вы сможете быстро найти и устранить источник проблемы.

Узнайте, как Google воспринимает ваш контент


Для любителей bleeding edge технологий мы создали альфа-версию инструмента «Просмотреть как Googlebot для приложений», чтобы вы могли проверить URI приложения и узнать, как Google его обрабатывает. Он также поможет выявить несоответствие между контентом в приложении и на сайте. В большинстве случаев такие ошибки возникают из-за блокировки доступа робота Googlebot к определенным ресурсам (о возможных проблемах подобных блокировок и путях решения мы недавно рассказывали на страницах нашего Хабраблога) или из-за всплывающих окон с предложением войти в аккаунт или зарегистрироваться. С помощью нового инструмента вы можете обнаружить такие проблемы и решить их.

Просмотреть приложение как Googlebot

Хотите получить преимущество проиндексированного Android-приложения прямо сейчас? Вперёд! Вносите изменения в AndroidManifest.xml, добавляйте разметку, необходимую для индексирования контента, публикуйте обновлённый .apk.

После этих нехитрых действий вы сможете добавить своё Android-приложение в Search Console и получать результаты анализа от Google.

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

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

JPEG 2000, JPEG-XR и WebP в стране упущенных возможностей

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

Попробуем разобраться, почему JPEG 2000, JPEG-XR и WebP все еще пасут задних, и действительно ли они такие классные, как заявлено.

JPEG 2000


Отличный формат сжатия, поддерживает компрессию как с потерями качества, так и без, а также прозрачность и прогрессивное сжатие. Заявлено сжатие на 20% лучше, чем в обычном JPEG, и при этом главной фишкой является отсутствие артефактов при сильной компрессии.
Недостаток – слабая поддержка, и от этого очень скудное распространение в сети.

JPEG-XR


Жмет фотки еще лучше и еще быстрее, чем JPEG 2000, возможен вариант lossless, при этом поддерживает разные степени прозрачности и прогрессивное сжатие. Сжимает якобы на 50…75% лучше, чем JPEG, при этом сохраняя приличное качество. Так заявлено. В конце материала поэкспериментируем и проверим, не разводят ли нас.
Поддержка — только старым добрым IE 9 и старше.

WebP


Является полностью открытым стандартом. Поддерживает как lossy, так и lossless, и компрессит картинки на 30…40% лучше JPEG’а. Единственный минус по сравнению с двумя предыдущими – не поддерживает прогрессивное сжатие. Зато гораздо лучше поддерживается браузерами и имеет более светлое будущее.

Поддержка


Не смотря на очевидные преимущества, ни JPEG 2000, ни JPEG-XR, ни WebP пока не светит занять место среди самых популярных форматов сети. Почему? Потому что договориться не могут. Посмотрим на поддержку:

Использование


Неправильно:
<img src="myimage.webp"/>


Так картинка правильно отобразится только в дружественном браузере.

Правильно:

<picture>   
<source srcset='myimage.jxr' type='image/vnd.ms-photo'>   
<source srcset='myimage.jp2' type='image/jp2'>   
<source srcset='myimage.webp' type='image/webp'>   
<img srcset='myimage-quant.png' alt='myimage'> </picture>


Встроенную поддержку &ltpicture> имеют только Chrome, Opera и последняя версия Firefox, но с помощью picturefill подстраиваемся и под другие браузеры. После загрузки скрипта добавьте к &lthead> следующее:
<script async=true src=/path/to/js/picturefill.js></script>


Сработает для WEBP and SVG. Для остальных форматов сразу после тега &ltscript> добавляем:
<script async=true src=/path/to/picturefill.js></script> 
<script async=true src=/path/to/jxr.js></script> 
<script async=true src=/path/to/jp2.js></script>


Ура. Картинка корректно отобразится в разных браузерах.

Сравниваем JPEG-XR и Webp


Мы решили на конкретном примере проверить, кто же лучше жмет картинки — JPEG-XR или WebP. Для этого мы собрали JPEG-картинки из лучших публикаций Хабры за последний месяц, и каждую поочередно сжали в WebP и в JPEG-XR с помощью этого и этого инструментов.
Средний показатель сжатия для JPEG-XR составил 48%, а для WebP — 60%. Если рассматривать каждую картинку отдельно, то в 80% случаев WebP справился с задачей лучше, чем JPEG-XR на 10...25%.

Вот, например, один и тот же манул, сжатый в JPEG-XR и в WebP.

Как видим, данные отличаются от заявленных.

Конспект


  • JPEG 2000, JPEG-XR и WebP — инновационные форматы, не получившие должного признания в вебе.
  • Ни один из браузеров не поддерживает хотя бы два из этих форматов.
  • К общему знаменателю можно прийти с помощью picturefill.
  • Вопреки заявленным значениям, WebP сжимает фотки в среднем на 10...25% лучше, чем JPEG-XR.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

[Перевод] Немного о синтаксисе Erlang

Изначально я планировал выпустить этот опус как дополнение к книге “Learn You Some Erlang”, однако его содержание больше соответствует редакционному материалу, нежели хорошему справочному документу, поэтому я решил просто написать об этом в блоге.

Многие новички в мире Erlang успешно изучают его и начинают играться, не вступая с ним в тесное знакомство. Я прочитал много жалоб именно на синтаксис и эти “козьи шарики” (ant turds — ориг.) — «веселый» способ называть символы ,, ;, .. Например, «Как же они бесят», а также многое другое.

Я упоминал в книге, что Erlang берет свое начало из Prolog. Это дает нам понять, откуда берутся все эти знаки препинания, но это, увы, не заставляет людей проникнуться любовью к подобной пунктуации. И правда, почему-то никто не говорит мне: «А-а! Prolog! Что ж ты раньше не сказал!» Ввиду этого я предлагаю три возможных способа человеческого чтения кода на Erlang, дабы сделать мир добрее.

Шаблон

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

В командной строке Erlang знак точки (.) означает конец выражения. Чтобы выполнить выражение 2+2, нужно поставить точку (и затем нажать Enter), чтобы оно выполнилось и вернуло что-нибудь.
Однако при написании модуля символ точки заканчивает Формы. Формы — это атрибуты модуля или объявления функций. Форма ничего не возвращает и поэтому не является выражением.

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

Но продолжим. Нам потребуется еще два правила:

  1. Запятая (,) разделяет выражения:
    C = A+B, D = A+C
    
    

    Просто как орех, не правда ли? Заметим, однако, что
    if ... end
    case ... of ... end
    begin ... end
    fun() -> ... end
    try ... of ... catch ... end
    
    
    — все суть выражения. Например, можно сделать следующее:
    var = if X > 0 -> valid;
             X =< 0 -> invalid
          end
    
    
    И получить значение на выходе if...end. Это объясняет, почему мы порой видим запятые (,) после этих языковых конструкций — это всего лишь означает, что далее у нас следует еще одно выражение, которое надо выполнить.
  2. Точка с запятой (;) выполняет две функции.
    1. Она разделяет различные определения функции:
      fac(0) -> 1;
      fac(N) -> N * fac(N-1).
      
      

    2. Она разделяет различные ветки выражений if … end, case … of … end и других:
      if X < 0 -> negative;
           X > 0 -> positive;
           X == 0 -> zero
      end
      
      

      Может показаться странным, что последняя ветка выражения не отделяется (;). Но ведь (;) разделяет ветки, но не заканчивает каждую из них. Надо думать в выражениях, а не в строчках. Некоторым легче читать код, если разделитель ставить следующим образом:
      if X < 0 -> negative
       ; X > 0 -> positive
       ; X == 0 -> zero
      end
      
      

      Такое форматирование лучше подчеркивает роль (;) именно как разделителя. Этот знак идет между ветками и условиями, а не после них.

Обобщив все вышесказанное, мы можем смело заключить, что если после выражения (например case...of...end) следует точка (,), то затем должно быть следующее выражение. Точка с запятой (;) ставится в конце ветки функции, а точка (.) на последней ветке функции.

Наше обычное представление, когда символом (;) мы разделяли строки (как, например, в C или Java), сейчас надо просто взять и выкинуть в окно. Вместо этого мы рассматриваем наш код как заполняемый шаблон (отсюда и название метода):

head1(Args) [Guard] ->
     Expr11, Expr12, …, Expr1N;
head2(Args) [Guard] ->
     Expr21, Expr22, …, Expr2N;
headM(Args) [Guard] ->
     ExprM1, ExprM2, …, ExprMN.
%% Где ExprIJ - это выражения


Указанные правила действительно работают, но нужно переключить свой мозг в иной режим чтения кода. Именно здесь заключается самый сложный переход: мы должны перейти от строк и блоков к предопределенному шаблону. Поясню: если вдуматься, то конструкции вроде
for (int i = 0; i >= x; i ++) { … }
// Или даже
for (...);

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

Предложение

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

Здесь мы сравниваем Erlang и язык (можно английский, можно русский). Представьте что вы составляете список вещей для поездки. Хотя нет, не будем представлять, вот он:

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


Если перевести это на язык Erlang, то все будет выглядеть очень похоже (К сожалению, в таком виде оно работать не будет, так как Erlang поддерживает UTF только в рамках строковых переменных, но никак не исходного кода. Там, по старинке, ISO-latin-1. — прим. пер.)
вещи(солнце) ->
    крем, вода, шляпа;
вещи(дождь) ->
    зонтик, куртка;
вещи(ветер) ->
    змей, рубашка.


Видите, можно просто заменить предметы на выражения и вот оно! А вот выражения вида if … end следует представлять просто как вложенные списки таких вещей.

И, Или, Конец

Еще один способ мне предложили на #erlang. В этом методе, увидев (,), надо читать “И”, (;) становится “ИЛИ” (как вариант, «А ЕЩЕ», — прим. пер.), а (.) означает “КОНЕЦ”. Таким образом объявление функции можно читать как набор вложенных логических предикатов и условий.

В заключение...

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

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Вебинары Hewlett-Packard

сегодня в 15:20

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

– как сэкономить на обслуживании сервера,
– решить проблему нехватки бюджета,
– сделать затраты на ИТ полностью предсказуемыми.

Специальные гости из компаний-партнеров HP расскажут про пути решения проблем, вызванных прекращением поддержки Windows Server 2003, поделятся лучшими практиками построения и развития сетей SAN.

Тех.консультанты HP в режиме реального времени проведут демонстрацию нового функционала MSA и системы управления IMC, руководитель учебного центра представит новые курсы и по традиции предоставит скидки участникам. Подробнее.

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

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Основы моделирования в openEMS

В прошлой части было рассказано как установить и настроить open-source электромагнитный симулятор openEMS . Теперь можно переходить к моделированию. Как производить моделирование ЭМВ при помощи openEMS и Octave будет рассказано в этой статье.

Мы будем моделировать процесс распространения электромагнитной волны (ЭМВ) между двумя параллельными металлическим пластинами.

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

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

Как было сказано в предыдущей части, все симуляции в openEMS являются скриптами Octave/Matlab. Запускаем Octave/Matlab и вводим следующие команды. Сначала инициализируем пространство. Мы создаём специальный объект FDTD, который описывает пространство конечной разности во временной области:

FDTD = InitFDTD('NrTS',100,'EndCriteria',0,'OverSampling',50);

Параметры функции — это 100 точек расчёта по времени от нуля. Шаг расчёта по времени выбирается автоматически на основе частоты Найквиста и частоты источника ЭМВ. Попробуйте задать другое количество точек, например 1000.

Теперь устанавливаем источник ЭМВ частотой 10 МГц. Здесь параметры функции понятны из названия.

FDTD = SetSinusExcite(FDTD,10e6);

Для любого моделирования ЭМВ нужны граничные условия. Граничные условия описывают свойства материала, которым ограничено пространств в направлении каждой из трёх осей координат X,Y,Z. Порядок следования граничных условий в параметрах функции следующий X+, X-, Y+, Y-, Z+, Z- У нас пространство по оси Y в положительном направлении ограничено идеально проводящей поверхностью (PEC — Perfect Electric Conductor), в отрицательном направлении по Y — также проводящей поверхностью. PMC — это идеальный
магнитопроводник. MUR — это абсолютно поглощающий диэлектрик. Он приблизительно соответствует материалу стенок безэховой камеры.

FDTD = SetBoundaryCond(FDTD,{'PMC' 'PMC' 'PEC' 'PEC' 'MUR' 'MUR'});

Ещё доступен специальный многослойный материал (PML_x) для граничных условий. Он может иметь от 6 до 20 слоёв (например PML_8, PML_10). Этот материал тоже действует как поглощающий диэлектрик.

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

CSX = InitCSX();

Теперь нужно создать сетку. Расчёт распространения ЭМВ будет выполняться внутри пространства, ограниченного сеткой. Сначала задаём размерность сетки по координатам (X*Y*Z=20х20*40 метров).

mesh.x = -10:10;
mesh.y = -10:10;
mesh.z = -10:30;

Теперь создаём собственно сетку в прямоугольных координатах при помощи функции
DefineRectGrid() и применяем её к геометрии (шаг сетки равен 1 метру):

CSX = DefineRectGrid(CSX,1,mesh);

Далее создаём источник ЭМВ. Задаём амплитуду ЭМВ и направление вектора ЭМВ. Для этого служит функция AddExcitation.
octave:16> CSX = AddExcitation(CSX,'excitation',0,[0 1 0]);

Первый и второй параметры функции — это имя CSX-пространства и имя источника ЭМВ соответственно. Третий параметр функции — это тип поля. Доступны следующие типы:

  • 0 — электрическое поле (Е), жёсткое возбуждение
  • 1 — электрическое поле (Е), жёсткое возбуждение
  • 2 — магнитное поле (Н), мягкое возбуждение
  • 3 — магнитное поле (Р), жёсткое возбуждение
  • 10 — плоская ЭМВ

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

Четвёртый параметр — это вектор, компоненты которого задают амплитуду ЭМВ по трём направлениям X,Y,Z.

Таким образом мы задали возбуждение электрическим полем амплитудой 1 В/м в направлении оси Y.

Теперь создаём площадку (AddBox) с которой будем распространяться ЭМВ. Эта площадка и является собственно источником ЭМВ.

CSX = AddBox(CSX,'excitation',0,[-10 -10 0],[10 10 0]);

На этом описание геометрии завершено. После того как мы описали геометрию, нужно создать сечение, в котором мы будем наблюдать распространение ЭМВ. Это делается при помощи функций AddDump() и AddBox().

CSX = AddDump(CSX,'Et');
CSX = AddBox(CSX,'Et',0,[-10 0 -10],[10 0 30]);

Теперь подготавливаем временный каталог для хранения результатов расчётов и просматриваем геометрию при помощи CSXCAD.

mkdir('tmp');
WriteOpenEMS('/tmp/tmp.xml',FDTD,CSX);
CSXGeomPlot('/tmp/tmp.xml');
invoking AppCSXCAD, exit to continue script...
QCSXCAD - disabling editing

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

RunOpenEMS('tmp','/tmp/tmp.xml','');
 ---------------------------------------------------------------------- 
 | openEMS 64bit -- version v0.0.32-14-g63adb58
 | (C) 2010-2013 Thorsten Liebig <thorsten.liebig@gmx.de>  GPL license
 ---------------------------------------------------------------------- 
        Used external libraries:
                CSXCAD -- Version: v0.5.2-15-gcb5b3cf
                hdf5   -- Version: 1.8.13
                          compiled against: HDF5 library version: 1.8.13
                tinyxml -- compiled against: 2.6.2
                fparser
                boost  -- compiled against: 1_54
                vtk -- Version: 5.10.1
                       compiled against: 5.10.1

Create FDTD operator (compressed SSE + multi-threading)
FDTD simulation size: 21x21x41 --> 18081 FDTD cells 
FDTD timestep is: 1.92583e-09 s; Nyquist rate: 25 timesteps @1.03851e+07 Hz
Excitation signal length is: 100 timesteps (1.92583e-07s)
Max. number of timesteps: 100 ( --> 1 * Excitation signal length)
Create FDTD engine (compressed SSE + multi-threading)
Running FDTD engine... this may take a while... grab a cup of coffee?!?
Time for 100 iterations with 18081 cells : 0.1624 sec
Speed: 11.1336 MCells/s

Симуляция завершена, и можно просмотреть результат. Запускаем Paraview. Затем выбираем File->Open и идём во временный каталог, где хранятся результаты симуляции. Там открываем файл Et_.vtr. Этот файл содержит информацию о результате расчёта процесса распространения ЭМВ во времени. Вот, что нужно открывать, путь к файлу у вас будет другой:

Теперь видим в окне Paraview плоскость, которая является сечением в котором мы смотрим амплитуду ЭМВ.

Чтобы визуализировать амплитуду ЭМВ, нужно в выпадающем списке Coloring выбрать E-field (по умолчанию там стоит SolidColor) и затем отобразить цветовую легенду (нажать Show). Теперь мы видим амплитуду ЭМВ в момент времени t=0. В начальный момент времени амплитуда ЭМВ тоже равна нулю во всём пространстве, поэтому вся плоскость будет закрашена в один цвет. Чтобы посмотреть распределение ЭМВ нужно установить время отличное от нуля и нажать кнопку Rescale. Теперь на плоскости отобразится распределение амплитуды ЭМВ.

Можно также запустить анимацию и просмотреть процесс распространения ЭМВ во времени. Как и следовало ожидать ЭМВ распространяется в обоих направлениях от плоскости-источника.

В результате мы смоделировали во временной области процесс распространения ЭМВ в некоторой области пространства. В заключении скрипт Octave/Matlab целиком:

FDTD = InitFDTD('NrTS',1000,'EndCriteria',0,'OverSampling',1);
FDTD = SetSinusExcite(FDTD,10e6);
FDTD = SetBoundaryCond(FDTD,{'PMC' 'PMC' 'PEC' 'PEC' 'MUR' 'MUR'});
CSX = InitCSX();
mesh.x = -10:10;
mesh.y = -10:10;
mesh.z = -10:30;
CSX = DefineRectGrid(CSX,1,mesh);
CSX = AddExcitation(CSX,'excitation',0,[0 1 0]);
CSX = AddBox(CSX,'excitation',0,[-10 -10 0],[10 10 0]);
CSX = AddDump(CSX,'Et');
CSX = AddBox(CSX,'Et',0,[-10 0 -10],[10 0 30]);
mkdir('tmp');
WriteOpenEMS('/tmp/tmp.xml',FDTD,CSX);
CSXGeomPlot('/tmp/tmp.xml');
RunOpenEMS('tmp','/tmp/tmp.xml','');

Ссылка на предыдущую статью по openEMS: http://ift.tt/1Snf0TS

Сайт проекта openEMS: openems.de

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.