Результати пошуку
ITVDN: курси програмування
Відеокурси з
програмування

Замовити дзвінок

Вибери свою IT спеціальність

Підписка

Замовити дзвінок

+38 099 757 27 82
Результати пошуку за запитом: видеокурс c*
Створення панелі умінь. Частина 1. Робота з Unity UI.

Автор: Олексій Мухняк

Введение Данной статей начинается серия публикаций о создании панели умений (skills panel) для вашей игры. Панели умений встречаются во многих RPG играх и не только. По мере создания панели умений будет рассмотрено много вспомогательных компонентов, таких как работа с пользовательским интерфейсом или Unity UI (user interface); использование компонентов Event System, Grid Layout Group, Outline; настройка Canvas; использование интерфейсов IPointerDownHandler, IPointerEnterHandler, IPointerExitHandler; и многое другое. В результате получится вот такая игра: Поскольку материал вышел довольно объёмным, то пришлось разделить его на части. Сегодня особое внимание уделим работе с Unity UI и настройкам Canvas. Создание сцены и настройка Canvas: Сначала нужно создать пустой 3d проект и добавить новую камеру для UI (GameObject > Camera), дадим ей имя UICamera. Изменим проекцию (projection) камеры на orthographic (размер объектов не зависит от расстояния). Выставим Clear Flags > Depth only, это даст прозрачную камеру без лишних фоновых добавлений. Поскольку UI должен обрисовываться поверх всего, то нужно изменить глубину камеры (Depth = 1). Далее создадим Canvas (GameObject > UI > Canvas), вмести с элементом Canvas создастся Event System, он необходим для обработки событий, которые происходят на Canvas (более подробно рассмотрим позже). Что же такое Canvas и для чего он нужен. Canvas переводится как «Холст» и представляет собой абстрактное пространство для настройки и отрисовки UI. Все UI элементы должны быть потомками Canvas. Рекомендуется использовать следующие настройки (они позволят автоматически подстраиваться под расширение экрана, очень удобно для мобильных устройств): Выбираем «Render Mod > Screen Space – Camera»UI. В поле «Render Camera» выбираем созданную нами UICamera. Далее остается изменить Canvas Scaler Sctipt, а именно поле «UI Scale Mode > Scale With Screen Size», что дает автоматическое изменение UI в зависимости от расширения экрана. На этом настойки Canvas закончены. Работа с Unity UI: Работать с UI элементами удобно в 2d режиме (это не обязательно, но значительно упростит процесс разработки UI), переключаться между 2d и 3d режимами можно «Scence > 2D». Все элементы UI содержат следующий компонент «Rect Transform» (в том числе и Canvas). Именно «Rect Transform» контролирует расположение UI относительно расширения экрана.  Рассмотрим возможности «Rect Transform» на простом примере. Сначала создадим кнопку (правой кнопкой мыши на элемент Canvas > UI > Button). Первое, что бросается в глаза - это синий круг и четыре треугольника в центре кнопки.  Четыре треугольника называют «Якорь», поскольку в зависимости от его расположения и настроек изменяют свое поведение UI элементы при изменении расширения экрана. Синий круг – это «центр» кнопки (или другого UI элемента), относительно него происходит вращение (Rotation) или масштабирование (Scale) элемента. Место расположения «центра» кнопки хранится в специфическом формате и за него отвечает поле «Pivot». Где хранится расположение «центра» в соотношении (координаты «центра» x и y поделить на ширину и высоту соответственно) относительно нижнего левого угла. То есть соотношение сторон зеленого и красного квадратов на рисунке ниже. Например, «Pivot X = 0.5, Y = 0.5» означает, что центр кнопки находится посередине кнопки. «Pivot X = 0, Y = 0» означает, что центр кнопки находится в левом нижнем углу. Далее рассмотрим работу «Якоря», он может работать в 2-х режимах. Режим 1 - это когда все четыре треугольника находятся в одной точке. Тогда компонент «Rect Transform» имеет следующие поля: Pos X, Pos Y, Pos Z, Width, Height. Как Вы уже догадались, Width, Height хранят значение ширины и высоты UI элемента (в нашем случае кнопки). Pos X, Pos Y, Pos Z отвечают за расстояние между центром «Якоря» и «центром» UI элемента. Возникает вопрос, а зачем нам нужен этот «Якорь». Ответ прост, при изменении размеров родительского UI элемента «Якорь» изменяет расстояние к «центру» текущего UI элемента пропорционально этим изменениям. «Якорь», как и «центр», хранит свои координаты в соотнесённом виде в поле Anchors.  Для режима 1 «Anchors > Min» и «Anchors > Max» совпадают. Очень важно запомнить, что в этом режиме изменяется только расстояние между «Якорем» и «центром», а поля Width, Height остаются низменными (поскольку Canvas настроен в режиме «Scale With Screen Size», то с изменением расширения экрана все UI элементы изменят свои размеры за счет автоматического изменения параметра Scale в самом Canvas). Режим 2 - это когда четыре треугольника разделены. И первое, что бросается в глаза - это изменения наших полей Pos X, Pos Y, Pos Z, Width, Height на Left, Top, Pos Z, Right, Bottom соответственно. Теперь четыре треугольника образовывают мнимый квадрат и расстояние от стороны этого квадрата к нашему UI элементу хранится в полях на Left, Top, Right, Bottom (функция Pos Z осталась неизменяемой и отвечает за глубину объекта).  Изменяя значения этих полей, меняется размер UI элемента, а не «Якоря». За «Якорь» по-прежнему отвечает поле Anchors, но теперь «Anchors > Min» и «Anchors > Max» не всегда будут совпадать. Теперь поле «Anchors > Min» отвечает за расстояние между Left и Bottom сторонами родительского и текущего UI элемента, а «Anchors > Max» - за расстояние между Top и Right сторонами. Теперь при изменении родительского объекта наш UI элемент изменит свои размеры (поскольку Canvas настроен в режиме «Scale With Screen Size», то с изменением расширения экрана все UI элементы изменят свои размеры за счет автоматического изменения параметра Scale в самом Canvas, и это даст дополнительные изменения всем элементам в режиме 2). Чтобы постоянно не таскать «Якорь» и «центр» вручную, разработчики Unity сделали несколько стандартных настроек. В них можно перейти, нажав на следующий элемент: Откроется следующие окно, где можно задать расположение «Якоря». Если хотите вместе с изменениями «Якоря» изменить положение «центра», то следует зажать клавишу «Shift» (появляется синий кружочек который и отвечает за «центр»). Также есть возможность сразу передвинуть UI элемент на нужную позицию, для этого нужно зажать клавишу «Alt» (можно зажимать «Alt» и «Shift» одновременно). Работа с Grid Layout Group. Для начала создадим тестовую сцену, создадим Canvas и добавим Plane (таким же способом, как  кнопку). Plane должен располагаться приблизительно следующим образом: Grid Layout Group можно добавить с помощью «Add Component»: Теперь все дочерние объекты Plane будут автоматически подстраиваться (изменять размеры и свое расположение) в зависимости от настроек Grid Layout Group. Для наглядного примера добавим 4 Image элемента дочерними к Plane. Чтобы отличать Image, загрузим туда различные спрайты.  Image1, Image2, Image3, Image4 было присвоено картинки цифр 1, 2, 3, 4 соответственно. Теперь, когда знаем, где какой элемент, начнем изучение Grid Layout Group. Padding отвечает за отступы дочерних элементов от сторон родительского объекта. Как видно на рисунке, 4-й Image не влезает в выделенные границы, поэтому его было перенесено на новую строку. Поле Spacing отвечает за расстояние между дочерними объектами. Поле Cell Size отвечает за размеры дочерних объектов.  Поле «Start Corner» отвечает за порядок размещения дочерних объектов.  Upper Left  размещает дочерние объекты слева на право и сверху вниз. Upper Right  размещает дочерние объекты справа налево и сверху вниз. Lower Left  размещает дочерние объекты слева направо и снизу вверх. Lower Right  размещает дочерние объекты справа налево и снизу вверх. Поле «Start Axis» указывает, в какую сторону будут начинать размещаться дочерние элементы (по умолчанию стоит «Horizontal»). То есть если дочерние объекты не влезают в ширину родительского, то происходит переход на новую строку. Для Vertical наоборот, если дочерние объекты не влезают в высоту родительского, то происходит переход на новую строку. Поле «Child Alignment» отвечает за автоматическое выравнивание дочерних объектов. Данное поле не сложное и напоминает выравнивание текста в Word. Остается последнее поле «Constraint», оно дает возможность создавать фиксированное количество строк или столбцов (по умолчанию стоит «Flexible», то есть нет фиксирования). Как видите, элемент Grid Layout Group очень простой, но иногда может значительно упростить работу и UI. Заключение. В этой части было особое внимание уделено работе с новым Unity UI, он стал намного удобнее и качественнее. Теперь нет нужды пользоваться посторонними плагинами, нужно лишь немного разобраться и можно создать любой интерфейс, адаптирующийся под расширение экрана (очень полезно для мобильных устройств). На этом первая часть статьи закончена, попробуйте поиграться с различными UI элементами (не забывайте изменять расширение экрана для экспериментов). Изменить расширение экрана можно в окне «Games», как показано на рисунке ниже: На этом все, всем удачи и до новых встреч.
Коротко про форми

Автор: Редакция ITVDN

Введение Формы – не самая простая тема в изучении HTML. Перемещаться по странице с контентом – это одно, а вот заполнять поля формы – совсем другое. Вот почему хороша идея добавить несколько элементов к форме. Labels Все поля формы должны иметь уникальный слой. За это отвечает тег label, что в свою очередь связывается с элементом формы через атрибут for. <form>         <label for="yourName">Your Namelabel>         <input name="yourName" id="yourName"> Плюсом использования labels также есть то, что они кликабельны, делая активным текущее поле формы. Атрибуты name и id обязательны: name нужен форме для управления полем, а id - для связи label с ним. Группы элементов и их заголовки Можно сгруппировать несколько однотипных полей имен (полное имя, фамилия и тд.) или адресов (Адрес1, адрес2, регион, страна, индекс и тд.), используя тег fieldset. Тегом legend определяется оглавление сгруппированных объектов. <form action="somescript.php">         <fieldset>             <legend>Namelegend>             <p>First name                 <input name="firstName">p>             <p>Last name                 <input name="lastName">p>         fieldset>         <fieldset>             <legend>Addresslegend>             <p>Address                 <textarea name="address">textarea>p>             <p>Postal code                 <input name="postcode">p>         fieldset> Большинство браузеров по умолчанию отображает группу элементов в рамке с названием сверху слева. Конечно, при желании все изменяется при помощи CSS. Выбор варианта Элемент optgroup объединяет в группу варианты выбора. Также нужен атрибут label. Браузеры автоматически сделают выпадающие списки из таких групп. <select name="country">         <optgroup label="Africa">             <option value="gam">Gambiaoption>             <option value="mad">Madagascaroption>             <option value="nam">Namibiaoption>         optgroup>         <optgroup label="Europe">             <option value="fra">Franceoption>             <option value="rus">Russiaoption>             <option value="uk">UKoption>         optgroup>         <optgroup label="North America">             <option value="can">Canadaoption>             <option value="mex">Mexicooption>             <option value="usa">USAoption>         optgroup>     select> Поля доступа Поля форм (группы элементов) нуждаются в возможности доступа без использования указателей (мыши). На помощь приходят такие элементы, как tab stops и access keys. Атрибуты access key и tabindex добавляются в теги input и legend. <input name="firstName" accesskey="f" tabindex="1"> Источник: http://www.htmldog.com/guides/html/advanced/forms/
Використання метатегів

Автор: Редакция ITVDN

Введение Метатеги никак не влияют на отображение содержимого веб-страниц, но их активно используют поисковые машины для сбора информации про сайт. Тег meta можно записать внутри элемента head безмерное количество раз с такими атрибутами, как charset, name, http-equiv и content. При применении атрибута name или http-equiv  content обязателен. Names Значения атрибута name разнообразные. Это и author, и description, и keywords. Author явно указывает на автора HTML- страницы, description обычно используется поисковыми машинами для отображение описания страницы в выдаче поиска. Поисковики активно используют метатеги для определения некоего доверия веб-страницам. Вот почему так важно использовать теги meta. Так, например, keywords очень широко используется (иногда слишком). Хотя, современные поисковые машины генерируют релевантный контент самостоятельно. HTTP эквиваленты Атрибут http-equiv может быть использован вместо name и сгенерирует HTTP название, что будет отправлено на сервер. Атрибут должен редко применятся, его значения: Content-type – оправляются зашифрованные данные; Default-style – предпочитаются стили с указанных источников; Refresh –определяется, как часто (в секундах) страница будет обновляться или пересылать на другую. Не очень разумно. Очень удобно использовать запись вместо аналогичного для определения кодировки страницы. <head>     <title>Air conditioners? YEAH conditioners!title>     <meta charset="utf-8">     <meta http-equiv="refresh" content="3">         <meta name="description" content="This is my really, really, REALLY exciting web page about air conditioners"> Источник: http://www.htmldog.com/guides/html/intermediate/metatags/ 
Використання форм у HTML

Автор: Редакция ITVDN

Введение Формы используются для сбора информации, внесенной пользователем. Введенные данные взаимодейстуют с веб-приложениями, например, или когда нужно отправлять информацию в Интернет. Формы сами по себе не очень полезные. Вместе с языком программирования их используют для обработки информации, введенной пользователем. Эти разнообразные скрипты нуждаются в других языках, отличающихся от HTML и CSS. Теги  form, input, textarea, select и option – базовые теги для форм в HTML. Form Тег form формирует такой себе «бланк». Если используется пользовательская форма для отправки данных, то нужно описать атрибут action для указания, куда контент будет отправлен. Атрибут method указывает форме, как данные будут отправляться на сервер, также имеет дефолтное   значение get, а также post, что фактически незаметно передает информацию о форме. Get применяется для более коротких участков неконфиденциальной информации с сайта. Например, поиск будет отображаться в адресе страницы результатов поиска. Значение post - для более продолжительных, более защищенных материалов, таких как контактные формы, например. Вот элемент формы будет выглядеть примерно так:     <form action="processingscript.php" method="post">     form> Input Тег Input  - чуть ли не важнейшее в формах. Он может принимать огромное число значений, самые распространенные: <input type=”text”> или просто <input> - стандартное текстовое поле. Также может иметь атрибут value, что превращает исходный текст в textbox. <input type=”password”> - похожий на textbox, однако символы скрыты от пользователя. <input type=”checkbox”> - кнопка с флажком, пользователь может задать режим вкл/выкл. Также может иметь атрибут checked ( <input type=”checkbox” checked> ), делает флажок «включенным». <input type=”radio”> - похожий на checkbox, пользователь может выбрать только одну радиокнопку из группы. Также может иметь атрибут checked. <input type=”submit”> - кнопка, что отправляет форму. Пользователь может изменять исходный текст формы через атрибут value, например  <input type="submit" value="Ooo. Look. Text on a button. Wow"> Обратите внимание на то, что тег input как и img, и br не имеет закрывающегося тега. Textarea Textarea – по сути, большое многострочное текстовое поле. Через атрибуты rows и cols задается число строк и столбцов соответственно, хотя можно управлять размером поля через CSS. <textarea rows="5" cols="20">A big load of texttextarea> Select Тег Select в паре с option создает выпадающий список.     <select>         <option>Option 1option>         <option>Option 2option>         <option value="third option">Option 3option>     select> Выбранное значение отправляется при подтверждении формы. Этим значением будет текст, заключенный в тег option, но будет отослано значение атрибута value, если он явно задан. Так, из примера выше, если выбран первый пункт, «Option 1» будет отправлено, если же третий - Тег option может иметь атрибут selected, аналогично как checked для checkbox и радиокнопок. Например, <option selected>Rodentoption> будет изначально выбран вариант “Rodent”. Names Все вышеописанные теги будут красиво размещаться на странице, но, если подключить скрипт для обработки формы – все они будут проигнорированы. Так случится потому, что поля формы должны иметь уникальные имена. Так что нужно добавить атрибут name во все поля: <input type="text" name="talkingsponge">   Пример формы: <form action="contactus.php" method="post">         <p>Name:p>         <p>             <input type="text" name="name" value="Your name">p>         <p>Comments: p>         <p>             <textarea name="comments" rows="5" cols="20">Your commentstextarea>p>         <p>Are you:p>         <p>             <input type="radio" name="areyou" value="male">             Malep>         <p>             <input type="radio" name="areyou" value="female">             Femalep>         <p>             <input type="radio" name="areyou" value="hermaphrodite">             An hermaphroditep>         <p>             <input type="radio" name="areyou" value="asexual">             Asexualp>         <p>             <input type="submit">p>     form> Источник: http://www.htmldog.com/guides/html/beginner/forms/
Фундамент внутрішньої оптимізації. 5 залізних факторів

Автор: Андрій Афанасьєв

Введение В начале данной статьи хочу поздравить Вас и себя со своей первой публикацией в 2016 году. Искренне желаю встречать на своем пути побольше ценной и интересной информации, а также людей, которые будут делиться бесценным опытом и помогут таким образом в Вашем профессиональном росте:) А теперь можно приступить непосредственно и к теме данной публикации. Я не сомневаюсь, что многие уже успели перелопатить массу книг и статей о том, какой должна быть качественная внутренняя оптимизация, на что она влияет, какие тренды нас ждут в наступившем году, поскольку такой информации в Интернете целые массивы. Но меня это не остановило. Я уверен, что данный материал обязательно откроет что-то новое, позволит расставить акценты и сосредоточить внимание на самом главном. Тем более, кто дочитает эту статью до конца, получит небольшой, но приятный бонус:) От слов к делу Самый встречаемый вопрос, особенно среди новичков, звучит так: ”Внутренняя оптимизация - такой трудоемкий процесс, так много факторов и пунктов проверки. Подскажи, на что стоит обращать внимание в первую очередь?”. Отвечаю. Пожалуй, на всё. Наша жизнь состоит из мелочей и SEO-оптимизация тому не исключение. Практически невозможно сложить красивую картинку из пазла на 100 или даже 1000 элементов, если упустить часть деталей.  Поэтому остается только сосредоточиться, сесть за компьютер, поставить возле себя чашку ароматного кофе или чая, открывать чек-лист, кропотливо и внимательно анализировать проект по каждому из пунктов. В результате Вы получите полноценный труд в виде технического задания, которое, с большой вероятностью, Вам самим понравится и после внедрения обеспечит эффективное дальнейшее SEO-продвижение. Но, несмотря на важность всех мелочей и нюансов, я подготовил материал, в котором выделю 5 моментов критической важности, то, без чего достигнуть крепких ТОПов и заполучить целевой трафик невозможно, с кратким комментарием по их решению. Плюс все будет лаконично и конструктивно, ведь вычитать «простынь» под силу не каждому :) Наших 5 железных факторов 1. Семантика&Структура Моментом №1 в SEO анализе и оптимизации является тот, насколько структура сайта позволяет его продвигать.  Довольно часто возникает такая ситуация, что клиент хочет или требует оптимизацию сайта под семантику, к которой сайт совершенно не готов структурно. На сайте может не быть нужной вложенности, категорий и подкатегорий, страниц отзывов и прайсов, без которых эффективной оптимизации под интересную для клиента семантику не получится. Поэтому, крайне важно параллельно выбирать и анализировать семантику, а также давать рекомендации и правки по структуре сайта. Семантика + структура - очень серьезная связка. Лучше согласовать и внедрить все моменты на берегу, чем когда Вы уже выйдете в открытое плаванье и придется грести веслами обратно. Но также важно помнить, что не любая семантика, которую предлагает или на которой настаивает клиент является правильной. В силу незнания он может быть убежден в одном, но в реальности дела могут обстоять иначе. Нивелируйте это своим погружением в бизнес и опытом. 2. Настройка карты сайта, ЧПУ и хлебных крошек. Если на предыдущем этапе все ОК, двигаемся дальше. Думаю, каждому из нас хоть раз приходилось заблудиться на улице. В этом случае так хочется у первого встречного прохожого здесь и сейчас получить толковую консультацию, как попасть на улицу, которую мы ищем. А если мы еще и торопимся на жизненно важную встречу, то градус ситуации накален вдвойне. Шучу) К чему все это? Правильная навигация важна и для поисковых роботов. Он не будет тратить время на то, чтобы сканировать страницы с непонятным назначением, уровнем вложенности и неизвестной глубины. Ему необходимо видеть эту структуру и навигацию. Поэтому на сайте обязательно должны быть настроены: Человекопонятные url-адреса ЧПУ Все url-адреса на сайте должны быть приведены к ЧПУ-виду и иметь вид http://url/. Кириллица должна трансформироваться в латиницу. В качестве разделителя слов в ЧПУ следует использовать дефис "-". Также будет неоспоримым плюсом, если в url-адресах будет соблюдаться полная вложенность, т.е. http://url/>/. Пример не ЧПУ адреса может выглядеть так: site.domain/index.php?id=75. Примером ЧПУ адреса для этой же страницы может быть site.domain/itvdn. После настройки ЧПУ следует также сделать 301 редирект с не-ЧПУ урлов на ЧПУ. В нашем случае это 301 редирект с site.domain/index.php?id=75 на site.domain/itvdn. Настройка ЧПУшек и соответствующих редиректов, как правило, решается подключением стандартных плагинов. Если речь идет о самописной системе, скорее всего нужно будет «допиливать» соответствующий функционал. Реализация «хлебных крошек» Breadcrumbs Под «хлебными крошками» подразумевается навигационная цепочка, которая отражает вложенность структуры и чаще всего располагается над или под основным текстовым заголовком страницы.     Реализация Breadcrumbs полезна не только для того, чтобы показать поисковику глубину структуры сайта, но и с точки зрения юзабилити. Посетителю будет всегда удобно выйти на уровень или два уровня выше, допустим в каталог, если со страницей товара он полностью ознакомился, но хочет посмотреть что-то еще. Карта сайта sitemap.xml Как правило, данные карты генерируются стандартными плагинами в зависимости от того, на какой CMS сделан сайт. Либо есть универсальные решения, например, специальная CMS для генерации карт, которая интегрируется в корень сайта и парсит всю его структуру, в результате чего и генерируется карта сайта. Адрес, по которому должна быть доступна карта, желательно делать site.domain/sitemap.xml. Но и это еще не все. Необходимо после генерации карты скормить ее поисковому роботу в GWT в разделе «Файлы Sitemap».     Если с содержанием карты будет что-то не в порядке, Вы увидите соответствующие предупреждения об этом, которые потребуется исправить. Хочу еще подчеркнуть, что генерация карты сайта происходит в самом конце внедрения ТЗ оп оптимизации, когда устранены дубли, настроены правильные ЧПУ и т.д.   3. Диагностика и устранение дублей. Дубли – это откровенное зло. Было бы Вам приятно, чтобы кто-то копировал Ваше поведение, одевался также, носил идентичную стрижку? Думаю, что вряд ли. И поисковые роботы в этом молодцы. Они такое рубят, занижают рейтинг целевых страниц и сайта в целом, если в его содержимом содержатся дубли. Каким образом их диагностировать? Для этого есть несколько методов. Самый простой - это воспользоваться данными по повторяющимся метатегам в разделе «Оптимизация HTML». Если дубли присутствуют, Вы увидите данные в таком виде:     Диагностировать дубли можно и с помощью программы NetpeakSpider. Такой вариант даже лучше в том плане, что он сканирует актуальную структуру сайта, а страницы в GWT сканируются периодически и информация может быть не первой свежести на момент, когда Вы ищите дубли. Дальше сам собой напрашивается вопрос о том, как нам избавиться от них. Если дубль полный, т.е является 100% клоном страницы, которую дублирует, стоит проставить 301 редирект с дубля на основную страницу и отправить данный дубль на принудительную переиндексацию в разделе «Просмотреть как Googlebot».     Существуют и другие методы борьбы с полными дубликатами, например, закрытие их в robots.txt и принудительное удаление через GWT. Но 301 редиректы считаются наиболее эффективным и правильным методом. В случае частичных дублей, например, когда дублируется только и/или и/или заголовки необходимо переписывать метатеги на дублях вручную, если их много, либо формировать и внедрять шаблоны метатегов, которые в результате генерации будут уникальными для каждой страницы. Пример шаблона автогенерации метатегов может выглядеть, например, так:       После активной борьбы по искоренению дублей Вы в идеале сорвете джек-пот в таком виде:     Резюмируя данный пункт, предлагаю раз и навсегда сказать «Нет!» дублям, вовремя проверять их и давать отпор! Едем дальше…   4. Борьба с аффилиатами Под аффилиатами подразумевается другой сайт клиента с такими же контактными данными, названием компании, структурой и тематикой. Поисковые системы “за естественную конкуренцию” и ведут борьбу с монополизацией рынка. Поэтому, склеивают аффилиаты, накладывая фильтры и занижая рейтинг сразу всех сайтов. По статистике 2 из 3 клиентов приходят к нам с аффилиатами. В их качестве зачастую выступают не самостоятельные сайты на отдельных CMS и доменах, а  площадки, сгенерированные на платформах типа Prom.ua или Allbiz. Это плохая практика и что в таком случае требуется делать? Алгоритм простой: Аргументируем клиенту всю ситуацию, запрашиваем доступы к аффилиатам, проверяем их. Добавляем каждый аффилиат в Google Webmaster Tools. Настраиваем 301 редиректы со всех страниц аффилиатов на главную страницу основного сайта. Отправляем на принудительную переиндексацию аффилиаты. Если нет возможности проставить 301 редирект, нужно воспользоваться опцией в GWT в разделе «Удалить URL-адреса».     Если внутри платформы нет возможности добавить сайт в панель вебмастеров (а такое случается часто), нужно просто согласовывать полное удаление сайта-аффилиата и ждать, когда он выпадет из индекса. Такой простой алгоритм действий позволил нам вывести не один сайт из-под фильтра. Вот один из кейсов нашей компании, где мы непосредственно применяли данную методику и вытащили сайт с самого дна поиска на первые позиции. Также бытует мнение, что достаточно изменить название компании, контактную информацию - и ситуация может измениться. Этот метод не работает. Не тратьте даже время на покупку новых телефонов и не ломайте голову, как бы себя по-новому еще назвать.   5. On-Page оптимизация Подразумевает заточку и оптимизацию конкретных целевых страниц под семантическое ядро.  Здесь важны следующие моменты: Написание и размещение оптимизированных метатегов. Подготовка и размещение полезного структурированного качественного текстового контента, при этом оптимизированного под нужные поисковые запросы. Помимо контента текстового следует использовать качественные (желательно “не тяжелые” по объему памяти) изображения на всю ширину страницы. Это еще в тренде. Не помешают также тематические видеоролики, которые точно повлияют на поведенческие факторы ПФ (снизят показатели отказов и увеличат время нахождения пользователя на странице). И многие другие интересные вещи, которые Вы узнаете дальше.   На десерт Как я и обещал в начале данной статьи, Вас ожидает сюрприз. Под этой статьей находится pdf-файл «Полный чек-лист seo-оптимизатора от Abweb». Запомните, что только титаническая работа позволит получить что-то стоящее не только в сфере SEO. Жду Ваших комментариев, до следующих публикаций! Полный чек-лист seo-оптимизатора от Abweb
Робота з посиланнями у HTML & CSS

Автор: Редакция ITVDN

Введение Буквы «H» и «T» в слове «HTML» означают «hypertext» – по сути, систему связанного текста. DOCTYPE html> <html> <head>     <title>My first web pagetitle> head> <body>     <h1>My first web pageh1>     <h2>What this ish2>     <p>A simple page put together using HTMLp>     <h2>Why this ish2>     <p>To learn HTMLp>     <h2>Where to find the tutorialh2>     <p><a href="http://www.htmldog.com">HTML Doga>p> body> html>   Атрибут href в тега <a> определяет адрес ссылки. Так если, например, Вы имеете другой файл "flyingmoss.html" в той же директории вашего проекта, то код будет следующим:  <a href="flyingmoss.html">The miracle of moss in flighta> С помощью ссылок также можно отправить пользователю часть той же страницы. Необходимо добавить атрибут id, например, <h2 id="moss">Mossh2>  и потом нужная ссылка будет такой: <a href="#moss">Go to mossa> Переходя по ней, пользователь перейдет на место в странице с указанным ID. Источник: http://www.htmldog.com/guides/html/beginner/links/
Робота з Touch в Unity3D

Автор: Олег Загородній

Введение Ни для кого не секрет, что в мобильных играх, в отличие от компьютерных, практически единственным “устройством ввода” является палец. То есть, все действия, которые пользователь выполняет в игре, совершаются благодаря прикосновениям к экрану, или же тачам (англ. touch – прикосновение). В этой статье мы с Вами рассмотрим, как можно правильно обработать тачи, разберем, в чем разница между глобальными и локальными тачами, а также реализуем обработку некоторых популярных жестов, которыми Вы оперируете не только в играх, но и в повседневном пользовании смартфоном – swipe и zoom. Разумеется, все это мы будем делать, используя исключительно встроенный функционал Unity3D, без внешних плагинов и ассетов. Наведем справки Перед тем, как начать, рассмотрим, какие возможности нам предоставляет библиотека для работы с тачами. В документации Unity видим, что разработчики движка рекомендуют использовать класс Input для получения доступа к данным об акселерометре и мульти-таче мобильного устройства. Это нас вполне устраивает. В обязательном порядке необходимо подключить пространство имен UnityEngine.EventSystems, ведь именно оттуда родом большинство интерфейсов и классов, которые нам сегодня понадобятся. Например, IPointerClickHandler, IDragHandler и многие другие. В конце концов, классы BaseEventData и PointerEventData, из которых мы будем доставать все необходимые данные о событиях, проживают по тому же адресу. Что ж, не стоит волноваться, если Вы видите эти имена впервые. Моя задача - сдружить вас и наставить на путь плодотворной разработки. Если у Вас уже имеется опыт работы с данными классами, надеюсь, смогу поведать о каких-либо интересных спецификах работы с ними и еще некоторыми компонентами. Ближе к делу  или “Что такое глобальные и локальные тачи?” Немного теории. Чтобы правильно реализовать все, что мы задумали, сначала разберемся, что такое глобальные и локальные тачи. Если вкратце, то глобальные тачи – это прикосновения к экрану устройства в любой точке. То есть, мы будем говорить, что необходимо обработать глобальный тач, если для игрового процесса не важно, где именно игрок ткнет пальцем в экран. Думаю, все видели в играх заставку после загрузки уровня с большими буквами “Tap to start” либо что-то в этом роде. Бывают настолько простые игры, что, по сути, все управление игроком производится исключительно такими вот глобальными тачами. Например, в Flappy Bird, 2 Cars и многих других. Разумеется, не всегда все так просто. Случается, нам необходимо обработать тач в определенной области экрана, или по какой-либо кнопке, или по объекту. Такие тачи мы с Вами будет именовать локальными, так как они должны производиться в некой локальной области. Причем принципы реализации обработки тачей по 2D объектам или же элементам UI и обработки тачей по 3D объектам на сцене немного отличаются. Эти нюансы мы также рассмотрим. То есть перед тем, как перейти к воплощению идеи в жизнь, хорошенько подумайте, где и какой вид тача будет использоваться, ведь от этого зависит, как далеко в лес мы пойдем и как много дровишек нарубим. Практика. Подготовим рабочее место, как на картинке. Также создадим новый скрипт HandleScript и прикрепим его на куб. Как же считать прикосновение к экрану? Если в случае с кликами мыши в классе Input есть методы GetMouseButton (...Up, ...Down), то для тачей соответствующие методы отсутствуют. Здесь все даже проще. Разработчики предоставляют свойство touchCount (только для чтения), в котором хранится количество тачей в текущем кадре. То есть, чтобы считать глобальный тач, нам необходима всего одна строчка в методе Update: using UnityEngine; using UnityEngine.EventSystems; public class HandleScript : MonoBehaviour { void Update () {      if (Input.touchCount > 0) Debug.Log("Global touch!"); } } Как только пользователь задумает ткнуть пальцем в экран (чего мы, по сути, и ждем), выражение в блоке условия вернет true и на консоль вылетит наше сообщение. Что может быть проще? Важно: проверить данный способ обработки на компьютере не получится, так как в свойство touchCount записывается именно кол-во тачей. Клики мыши не в счет. Примечание: К примеру, при портировании на Windows Phone сообщения консоли, разумеется, отображаться не будут. Так что стоит реакцию на тач сделать более явной. Допустим: if (Input.touchCount > 0) transform.localScale *= 1.1f; Я специально буду обращать Ваше внимание на многие нюансы (для кого-то известные и очевидные, а для кого-то - нет), чтобы избавить от мелких и неприятных ошибок и сберечь парочку нервных клеток. Попробуйте сбилдить на свой смартфон и немного потапать в разных частях экрана. Что касается локальных тачей, то здесь есть несколько вариантов обработки. Также они зависят и от типа  объекта – 2D или 3D. Начнем, пожалуй, с 2D объектов. Давайте добавим на сцену какой-либо спрайт и сразу прилепим ему компонент 2D Box Collider (о нем чуть ниже). Еще добавим к этому спрайту наш скрипт HandleScript, но немного его подкорректируем. В Unity есть перечень методов, которые являются обработчиками определенных событий. Например, метод OnCollisionEnter вызывается, когда два твердых (Rigidbody) объекта соприкасаются, если вкратце. Так вот, среди вышеупомянутого перечня методов есть такой себе OnMouseDown метод. Он вызывается, как вы уже, наверное, догадались, в момент нажатия левой кнопки мыши непосредственно на объекте. Здесь есть три важных момента: Метод вызывается непосредственно в момент нажатия кнопки, а не отпускания или полного клика. Метод реагирует только на левую кнопку мыши. Срабатывает только при клике непосредственно на объект. Так как мы с Вами обрабатываем тачи, а не клики, то справедливы для нас будут только первый и третий пункты. То есть работу с человеческими пальцами данный метод тоже поддерживает. А может, и не только человеческими... Как же будет выглядеть наш код? using UnityEngine; using UnityEngine.EventSystems; public class HandleScript : MonoBehaviour { void OnMouseDown() {      transform.localScale *= 1.1f; } } Обратите внимание на сигнатуру метода и запомните. Ведь если сделать малейшую опечатку, событие касания/клика обрабатываться не будет. Проверить работу этого способа уже проще. Учитывая, что метод OnMouseDown реагирует как на мышь, так и на пальцы, билдить проект на смартфон не обязательно. Из этой серии есть еще метод OnMouseUp, который вызывается при отпускании пальца/кнопки. Важно: все события, связанные с кликами, движок Unity считывает, неявно используя Raycast’ы (лучи). Именно поэтому мы добавили на наш спрайт компонент 2D Box Collider. Если Вы еще не знаете, в чем суть работы Raycast’ов, обязательно почитайте в документации Unity. Важно: получается, указанные методы срабатывают при тапе/клике именно по коллайдеру объекта, а не по мэшу(Mesh)/спрайту. Попробуйте сбилдить и потапать на спрайт ящика либо зеленого куба. Теперь отключите их коллайдеры и проверьте, обрабатывается ли событие. Как видите, этот способ позволяет обработать тап как по 2D, так и по 3D объекту. Просто? Следующий способ обработать локальный тач тоже работает для обоих типов объектов, но немного отличается конфигурацией компонентов. Здесь мы с Вами будем уже работать с таким пространством имен, как UnityEngine.EventSystems. Если оно у Вас еще не подключено, самое время это сделать. Там, как я уже говорил, находятся необходимые нам интерфейсы и классы. Теперь обязательно добавьте на сцену объект EventSystem. Он находится во вкладке UI контекстного меню создания объекта. Итак, чтобы считать тап по 2D объекту (не элементу UI), необходимо обязательно прикрепить к камере компонент Physics 2D Raycaster. Для данного компонента обязательным является присутствие компонента Camera. Поэтому совсем неудивительно, что мы цепляем его именно на объект Main Camera. То есть после всех наших манипуляций игровая сцена должна выглядеть, как на картинке. Теперь, пожалуй, в код. Данный метод более универсальный, чем предыдущий, так как позволяет получить множество информации о состоянии курсора. Неважно, кто им управляет – палец или мышь. Нам понадобится интерфейс IPointerDownHandler из подключенного пространства имен. После реализации единственного его метода, получаем код, не менее простой, чем раньше. using UnityEngine; using UnityEngine.EventSystems; public class HandleScript : MonoBehaviour, IPointerDownHandler { public void OnPointerDown(PointerEventData eventData) {      Debug.Log(eventData.position); } } Разумеется, ошибиться с сигнатурой метода у вас не выйдет, так как Visual Studio сразу ругнется за нереализованный интерфейс. А в параметре eventData типа PointerEventData будет храниться вся информация о курсоре на момент срабатывания метода, а это очень полезно. Что же будет происходить? Здесь тоже все просто. В момент касания движок Unity пустит луч в сцену и в случае, когда тот пройдет сквозь коллайдер нашего спрайта, сработает метод обработчик OnPointerDown и в параметр eventData запишется вся информация о курсоре. Для считывания тачей также есть следующие интерфейсы: IPointerUpHandler, IPointerClickHandler, IPointerEnterHandler и IPointerExitHandler. Мне кажется, по их именам предельно ясно, какой из них какое событие позволяет обработать. Все, что Вам необходимо – наследоваться от нужного интерфейса, реализовать единственный его абстрактный метод и удивиться, как просто это работает. Главное, когда будете работать, не забудьте о компоненте Physics 2D Raycaster и объекте EventSystem, которые упоминались выше. Как вы уже, наверное, заметили, на 3D объекты данный способ не распространяется. Как это исправить? Элементарно. На объект-камеру необходимо также прикрепить компонент Physics Raycaser. Вот и все. Остальная суть остается та же. Попробуйте запустить проект. Заметили? Движок реагирует на клики мыши тоже. Теперь портируйте на ваш смартфон и удостоверьтесь, что все работает верно. Чтобы обработать тачи по элементам UI, Вам необходим будет компонент Graphic Raycaster. Но для него обязательным является компонент Canvas. Это, думаю, тоже вполне логично. Если прикрепить его на объект Canvas, то методы рассмотренных нами интерфейсов позволят также обработать тачи по кнопкам, панелям, тогглам и т.д. Итог по разделу о глобальных и локальных тачах. Давайте немного подсуммируем все, что только что было рассмотрено. Все тачи и клики обрабатываются неявным пусканием лучей из экрана в сцену. То есть определяется касание к коллайдерам объектов. При использовании интерфейсов из пространства имен UnityEngine.EventSystems обязательно надо добавить объект EventSystem. Physics 2D Raycaster – компонент для обработки тачей/кликов по 2D объектам. Physics Raycaster – компонент для обработки тачей/кликов по 3D объектам. Graphic Raycaster – компонент для обработки тачей/кликов по элементам UI. В отличие от предыдущих присутствует на объекте Canvas по умолчанию. Обработка Swipe жестов Как же выловить эти Swipe жесты и как определить их направление? На самом деле, это совсем несложно. Есть несколько интерфейсов, которые позволят нам это сделать:    IDragHandler, IBeginDragHandler, IEndDragHandler. Причем, они отлично подходят как для работы с Drag, так и Swipe жестами. Давайте почистим нашу сцену и приведем ее примерно вот к такому виду: У нас на объекте Canvas есть красная панель размером на весь экран и внутри нее имеется еще одна небольшая панель. Мы с Вами будем считывать Swipe’ы по красной панели и в зависимости от их направления двигать зеленую. Все до безобразия просто. Аналогичные действия Вы потом сможете проделать не только с элементами UI, как в этом примере, но и с 2D и 3D объектами. Сейчас же будем использовать панели, так как это получится более наглядно. Скрипт HandlerScript прикрепляем к внешней (красной) панели. using UnityEngine; using UnityEngine.EventSystems; public class HandleScript : MonoBehaviour, IDragHandler, IBeginDragHandler { public void OnBeginDrag(PointerEventData eventData) { } public void OnDrag(PointerEventData eventData) {  } } Вот как изначально должен выглядеть наш скрипт. Мы должны наследоваться он интерфейсов IDragHandler и IBeginDragHandler. Этого будет достаточно, чтобы считать Swipe. Скажу даже больше. Мы будем использовать только метод из второго интерфейса. Важно: необходимо обязательно реализовать интерфейс IDragHandler (пусть даже методом с пустым телом), чтобы срабатывали методы из интерфейсов IBeginDragHandler и IEndDragHandler. Дабы определить направление Swipe’а, мы будет использовать свойство delta в параметре eventData метода OnBeginDrag. В это свойство записывается разница позиций курсора между текущим и предыдущим кадрами. Мы просто напросто в момент начала Swipe’а глянем, какое значение этой дельты, и из этого уже определим, какое направление жеста. Возможно, у Вас возник вопрос. Откуда возьмется эта дельта, если метод OnBeginDrag сработает сразу, как только игрок начнет вести пальцем по экрану? Дело вот в чем. Этот метод вызывается только после того, как игрок сдвинет палец на какое-то пороговое значение расстояния от начальной точки. За это время успевает накопиться некоторая информация о происшедшем событии. То есть за этот небольшой промежуток времени мы можем определить, куда пользователь собирается вести свой палец. Мы всего лишь должны построить правильную условную конструкцию для определения направления и, исходя из условия, двигать зеленую панель в соответствующем направлении. В будущем это может быть ваш игрок в раннере или что-либо иное... using UnityEngine; using UnityEngine.EventSystems; public class HandleScript : MonoBehaviour, IDragHandler, IBeginDragHandler { Transform green;   // здесь будет ссылка на компонент Transform зеленой панели. void Start() {      green = transform.GetChild(0); // получаем ссылку на Transform зеленой панели. } public void OnBeginDrag(PointerEventData eventData) {      if (Mathf.Abs(eventData.delta.x) > Mathf.Abs(eventData.delta.y))      {             if (eventData.delta.x > 0) Debug.Log("Right");             else Debug.Log("Left");             green.position += new Vector3(eventData.delta.x, 0, 0);      }      else      {             if (eventData.delta.y > 0) Debug.Log("Up");             else Debug.Log("Down");             green.position += new Vector3(0, eventData.delta.y, 0);      } } public void OnDrag(PointerEventData eventData) { } } Что мы сделали? Сначала проверили, дельта по какой оси больше – X или Y? Если по оси X, значит движение будет по горизонтали, если же по Y – значит, по вертикали. А там еще раз проверили направление. Как видите, это делается элементарно просто, а работает безотказно. Обязательно проверьте, обрабатывается ли жест Swipe у вас на смартфоне. Если же Вам необходимо получить непосредственно угол Swipe’а, можно использовать формулу , которая позволяет вычислить синус угла прямоугольного треугольника из отношения противоположной и прилегающей сторон. Обработка Zoom’а Вернем сцену к первоначальному состоянию. Чтобы считать жест zoom’а, нам необходимо обработать глобальные тачи, поэтому наш скрипт HandleScript можно прикрепить даже на камеру. А код наш будет выглядеть вот так: using UnityEngine; public class HandleScript : MonoBehaviour { public float sensitivity; Vector2 f0start; Vector2 f1start; void Update() {      if (Input.touchCount < 2)      {             f0start = Vector2.zero;             f1start = Vector2.zero;      }      if (Input.touchCount == 2) Zoom(); } void Zoom() {      if (f0start == Vector2.zero && f1start == Vector2.zero)      {             f0start = Input.GetTouch(0).position;             f1start = Input.GetTouch(1).position;      }      Vector2 f0position = Input.GetTouch(0).position;      Vector2 f1position = Input.GetTouch(1).position;      float dir = Mathf.Sign(Vector2.Distance(f1start, f0start) - Vector2.Distance(f0position, f1position));      transform.position = Vector3.MoveTowards(transform.position, transform.position + transform.forward, dir * sensitivity * Time.deltaTime * Vector3.Distance(f0position, f1position)); } } В чем суть его работы?  Если пользователь прикасается к экрану двумя пальцами, координаты двух тачей записываются в соответствующие поля f0start и f1start. Именно с ними будут сравниваться все остальные позиции тачей, пока игрок не уберет от экрана пальцы. То есть мы просто сравниваем расстояние между двумя тачами. Если текущее расстояние меньше, чем начальное, то камера будет двигаться назад, если же больше – вперед. Условная конструкция в методе Zoom для того, чтобы позиции тачей записались в свойства только один раз в момент касания к экрану. Чувствительность zoom’а вы можете регулировать значением поля sensitivity прямо в окне Inspector. Попробуйте усовершенствовать этот скрипт сами. Допустим, сделать, чтобы сравнивались позиции не текущих и начальных тачей, а позиции тачей в этом и предыдущем кадре. Сравните результат. Заключение Как видите, обработка тачей и рассмотренных нами жестов реализуется очень просто. Все, что Вам необходимо – внимательность и фантазия. Если что-то не работает, обязательно проверьте, присутствуют ли необходимые компоненты на всех объектах, вызываются ли нужные методы и так далее. Совсем не обязательно искать внешние библиотеки, плагины и ассеты для того, чтобы работать с тачами в Unity. Разработчики предоставляют, по сути, всё, что вам может понадобится. Результат же зависит от Вашей фантазии. Не забывайте заглядывать в документацию Unity, там есть много всего интересного. Хотя, среди того, что мы сегодня рассмотрели, есть  вещи, о которых там не упоминают. Благодарю за внимание и желаю всем творческих успехов!
Робота з текстом: Адреси, Визначення, 2-спрямованість та редагування

Автор: Редакция ITVDN

Введение Должно быть, Вы уже знаете, что существует огромное количество текстовых тегов. Вы знакомы с параграфами, заголовками и даже аббревиатурами. Но существует множество других, более непонятных и сложных тегов. Непонятных, потому что вы вряд ли найдете их в интернете, и не потому что они не нужны. Если Вы найдете текст с объяснениями, то используйте новые для себя элементы для создания более качественного, лучшего, более значимой HTML-страницы. Адреса Тег address используется специально для контактных данных или всей веб-страницы (единожды). Это не значит, что address нужно обязательно применять для всех старых адресов. <h3>Author contact detailsh3> <address> <ul> <li>0123-456-7890li> <li>author_dude@noplaceinteresting.comli> <li>http://www.noplaceinteresting.com/contactme/li> ul> address> Определения Тег dfn используется для выделения первого термина. Как и тег abbr, атрибут title может быть использован для описания термина. <p>Bob's <dfn title="Dog">caninedfn> mother and <dfn title="Horse">equinedfn> father sat him down and carefully explained that he was an <dfn title="A mutation that combines two or more sets of chromosomes from different species">allopolyploiddfn> organism.p> Двунаправленный текст Тег bdo может использовать обратное направление текста, следовательно, может отображать языки, что читаются справа налево. Атрибут dir может принимать значения ltr (слева направо) или rtl (справа налево). <bdo dir="rtl">god lmthbdo> Редакции Теги ins и del используются для отображения соответственно вставленных и удаленных частей. Они не имеют ограничений применения в тексте, также могут быть применены для целых разделов контента и, как правило, используются в «Track Changes» - дословно «отслеживание изменений». Теги редакции также имеют атрибуты datetime, чтобы показать, когда была произведена правка, а также cite – причины изменений. <p>I have decided to <del datetime="2013-01-26">decreasedel><ins cite="http://www.icecreamforall.com/changeofpolicy/">increaseins> the amount of free ice cream that the State will provide for its citizens.p> Как и в обычных текстовых редакторах, элемент ins применяют для подчеркивания текста, а для зачеркивания – del. Источник: http://www.htmldog.com/guides/html/intermediate/text2/
Framework у С# для перевірки відбитків пальців

Автор: Редакция ITVDN

Введение В наше время распознавание отпечатков пальцев является активным направлением исследований. Важным компонентом в системе распознавания отпечатков является алгоритм. В связи с проблемой данной сферы алгоритмы распознавания отпечатков пальцев делятся на две категории: алгоритмы проверки и идентификации. Цель алгоритмов проверки отпечатков пальцев является – определить, какой из двух отпечатков сделан одним пальцем, а какой нет. С другой стороны, алгоритмы идентификации делают поиск запроса отпечатка пальца в базе данных, ища отпечаток, сделанный одним и тем же пальцем. Насколько мы знаем, существуют сотни документов, касающихся проверки отпечатков пальцев, но нет ни одного фреймворка, позволяющего проверять отпечатки в сети. Поэтому вы должны осуществлять ваши личные настройки, тестировать выполнения алгоритмов распознавания ваших отпечатков. Более того, вы должны потратить много времени, выполняя алгоритмы других авторов, для сравнения с собственными. FVC-onGoing – наиболее связанный с работой нашего фреймворка в веб-системе. Данная система имеет такие ограничения: У вас нет доступа к другим алгоритмам, кроме своих. Это не фреймворк, поэтому вы не можете использовать другие компоненты программного обеспечения. Система не может быть использована с целью обучения, так как ученик не может посмотреть, как работают алгоритмы. После выполнения опыта используется база данных (стандартная или жесткая), вам необходимо ждать 30 дней для, того чтобы сделать следующий эксперимент, используя ту же базу данных. Вы не можете управлять базой данных. Таким образом, вы не можете использовать собственную базу данных либо редактировать существующую. Отсутствует доступ к тем отпечаткам, для которых ваш алгоритм не выполнился. Следовательно, вы не сможете проанализировать, почему ваш алгоритм не выполнился для того, чтобы исправить код. Вы не сможете создать эксперимент с помощью обычного протокола, для оценки выполнения Если в любом из указанных выше ограничениях для вас возникли проблемы, тогда используйте наш фреймворк. Наш фреймворк реализован на С# с использованием .Net Framework по двум главным причинам. Во-первых, С# стал одним из самых популярных языков программирования. Вторая причина в том, что инструменты, библиотеки и классы, доступные в .Net Framework, экономят много времени написания кода. Наш фреймворк позволяет экспериментировать в базах данных типа B от FVC2000, FVC2002 и FVC2004, и в базах данных типа А от FVC2002 и FVC2004. В этих экспериментах мы выполняем индикаторы the Fingerprint Verification Competitions (EER(%), FMR100(%), FMR1000(%), ZeroFMR(%), Time(ms) и ROC curves).  Кроме того, вы можете делать опыты даже с обычным протоколом и разными базами данных. Мы реализовали алгоритмы распознавания отпечатков пальцев, предложенный Tico и Kuosmanen, Jiang и Yau, Medina-Pérez и Qi. Важно обратить внимание на то, что вопреки алгоритму Qi - это набор шаблонов отпечатков пальцев, основывающийся на алгоритмах, мы реализовали только алгоритмы, сопоставимые протоколами ввода отпечатка пальца. Мы также сделали алгоритмы выделения признаков, предложенный Ratha, и ориентацию на получение изображения предложенную Sherlock. Данный фреймворк позволяет вам добавлять, как новые алгоритмы распознавания отпечатков, так и новые алгоритмы выделения признаков с минимальными усилиями и без перекомпиляции фреймворка. Одна из целей, которую мы преследовали, когда разрабатывали данный фреймворк, была сделать классы интерфейсов простыми и доступными. Таким образом, процесс добавления новых алгоритмов очень прост. В этой статье мы вкратце объясняем, как: экспериментировать над распознаванием отпечатков пальцев; увидеть шаблон отпечатка пальца после выполнения алгоритма; высчитать и вывести на дисплей отпечаток пальца; интегрировать ваши алгоритмы в фреймворк. Расширения данного фреймворка с целью исследований появились в https://sites.google.com/site/miguelmedinaperez/software/fprframework В данной статьей мы вкладываем следующие файлы: FingerprintRecognition_v2.2.zip: исходные файлы нашего фреймворка. Help.zip: Исходный код документации. Запуск исследования для распознавания отпечатков пальцев Извлеките файл “FingerprintRecognition.zip” и постройте решение. Далее вы можете отлаживать проект “FR.FVCExperimenter” или можете запустить “FR.FVCExperimenter.exe” в директорию, которая содержит сгенерированный узел. Данное окно откроет: В строке “Resources” записан путь к базе данных, которую вы собираетесь использовать, к примеру: “D:\PR Databases\Fingerprints\FVC2004\DB1_B”. Выберите подходящий вам тип опыта в всплывающем меню с названием “Experiment”. Используйте меню с названиями “Minutia Extractor”, “Orientation Image Extractor” и “Skeleton Image Extractor“ для выбора алгоритма, который будет использоваться для нахождения основных особенностей (отпечаток, ориентированное изображение и его образ). Используйте поле “Matcher” для выбора алгоритма распознавания отпечатков пальцев и поле “Feature Provider” для выбора алгоритма, который будет хранить и извлекать черты выбранных совпадений. Несмотря на то, что мы реализовали только одну черту распознавания для каждого совпадения, существуют сценарии, где вы используете несколько признаков для одного совпадения. Поле с названием “Properties” позволяет изменять параметры выбранного алгоритма. Кликните на кнопку “Execute Experiment” для запуска исследования. Данный опыт использует протокол оценки от the Fingerprint Verification Competitions. В этом опыте мы высчитали такие индикаторы: EER(%), FMR100(%), FMR1000(%), ZeroFMR(%), Время(мс) и  ROC-кривая. Эти индикаторы сохранены в файле с именем, сформированным в зависимости от выбранного вами алгоритма и окончанием ".Summary.csv". Этот файл сохраняется в папке с названием "Results" в той же папке, где хранятся отпечатки пальцев. Также сохранены еще два файла, один хранит в себе ложные соответствия отпечатков пальцев, другой – ложные несоответствия отпечатков. Если вы хотите сравнить 2 отпечатка и проверить их совпадение, кликните на кнопку “Visual Match”, после которой откроется форма “Visual Fingerprint Matching”. Загрузите отпечатки, которые вы хотите сравнить и нажмите кнопку “Match”. Экстрактор признаков и выбранный в “FVC Experimenter” режим также здесь используются для того, чтобы выполнить сравнение отпечатков пальцев. Ниже пример сравнения двух отпечатков. Визуализация очертаний отпечатка пальца Если вы хотите вывести картинку очертания отпечатка, тогда вам нужно использовать проект “FR.FeatureDisplay”. В поле “Fingerprint Feature Display” вы можете изменять экстрактор признаков и их изображение. В фреймворке мы используем классы для визуализации отпечатка, ориентированное изображение и скелет картинки. В следующем примере вы можете увидеть визуализацию приблизительного изображения отпечатка: Соответствие отпечатков вне фреймворка В данном разделе представлен пример использования фреймворка для сравнения двух изображений отпечатков в обычном пользовательском приложении. Он складывается из 3 шагов для сравнения 2 изображений отпечатков: загрузить картинку, извлечение признаков и их сравнение. В этом случае пользователям нужно добавить ссылки из их приложения к сборке FR.Core и FR.Medina2012. Сборки SHullDelaunayTriangulation и ImageProcessingTools должны быть добавлены в папку вывода, где появится бинарный файл. // Loading fingerprints var fingerprintImg1 = ImageLoader.LoadImage(fileName1); var fingerprintImg2 = ImageLoader.LoadImage(fileName2); // Building feature extractor and extracting features var featExtractor = new MTripletsExtractor() { MtiaExtractor = new Ratha1995MinutiaeExtractor() }; var features1 = featExtractor.ExtractFeatures(fingerprintImg1); var features2 = featExtractor.ExtractFeatures(fingerprintImg2); // Building matcher and matching var matcher = new M3gl(); double similarity = matcher.Match(features1, features2); Пример использования M3gl  показывает, как легко использовать фреймворк, и как хорошо сложен и не требует пояснений код. Правила хорошего дизайна применены в фреймворке и дают возможность пользователю легко заменить или изменить любой компонент. Добавление новых алгоритмов в фреймворк Первое, что вы должны знать - это то, что вам не нужно модифицировать приложение фреймворка для распознавания собственных алгоритмов, потому что мы используем Рефлекцию, для того чтобы загрузить все динамические алгоритмы во время выполнения. Вы можете создать столько приложений, сколько хотите в директории, которая содержит фреймворк. Для каждого нового приложения зайдите в настройки и укажите путь вывода со значением “..\bin\Release\”. Для добавления новой функции определения вам нужно наследовать с базового класса FeatureExtractor и реализовать метод ExtractFeatures(Bitmap image). Например, предположим, что вы хотите создать функцию определения типа MyFeature, дальше вы можете реализовать класс по примеру:  public class MyFeatureExtractor : FeatureExtractor {     public override MyFeature ExtractFeatures(Bitmap image)     {         // Place here your code to extract features     } } В случае, если новая функция была построена на некоторых существующих, вы можете поступить следующим образом: public class MyFeatureExtractor : FeatureExtractor {     public FeatureExtractor<List> MtiaExtractor { set; get; }     public FeatureExtractor OrImgExtractor { set; get; }     public override MyFeature ExtractFeatures(Bitmap image)     {         try         {             var mtiae = MtiaExtractor.ExtractFeatures(image);             var orImg = OrImgExtractor.ExtractFeatures(image);             return ExtractFeatures(mtiae, orImg);         }         catch (Exception e)         {             if (MtiaExtractor == null)                 throw new InvalidOperationException("Cannot extract MyFeature: Unassigned minutia list extractor!", e);             if (OrImgExtractor == null)                 throw new InvalidOperationException("Cannot extract MyFeature: Unassigned orientation image extractor!", e);             throw;         }     }     public MyFeature ExtractFeatures(List mtiae, OrientationImage orImg)     {         // Place here your code to extract features     } } Для каждой функции определения вы должны создать поставщик ресурса. Поставщик ресурса позволяет сохранять (полученный) в (выходной) файл ресурс, связанный с отпечатком. Фреймворк включает в себя поставщик ресурса для извлекания отпечатков (MinutiaListProvider), ориентированное изображение (OrientationImageProvider) и скелет картинки (SkeletonImageProvider). В следующем примере поставщика ресурсов для функции извлекания определены ниже. public class MyFeatureProvider : ResourceProvider {     public MinutiaListProvider MtiaListProvider { get; set; }     public OrientationImageProvider OrImgProvider { get; set; }     public override string GetSignature()     {         return "myf";     }     public override bool IsResourcePersistent()     {         return true;     }     protected override MyFeature Extract(string fingerprint, ResourceRepository repository)     {         try         {             var mtiae = MtiaListProvider.GetResource(fingerprint, repository);             var orImg = OrImgProvider.GetResource(fingerprint, repository);             return featureExtractor.ExtractFeatures(mtiae, orImg);         }         catch (Exception e)         {             if (MtiaListProvider == null)                 throw new InvalidOperationException("Unable to extract MyFeature: Unassigned minutia list provider!", e);             if (OrImgProvider == null)                 throw new InvalidOperationException("Unable to extract MyFeature: Unassigned orientation image provider!", e);             throw;         }     }     private MyFeatureExtractor featureExtractor = new MyFeatureExtractor(); } Пришло время создать новый алгоритм совпадения отпечатков пальцев. Предположим, вы хотите сравнить функции типа MyFeature, для этого вам необходимо создать «сравнитель» такой как: public class MyMatcher : Matcher {     public override double Match(MyFeature query, MyFeature template)     {         // Place here your code to match fingerprints     } } В случае, если вы реализовали алгоритм сравнения отпечатков, дальше вам необходимо изменить в коде ниже следующее: public class MyMatcher : Matcher, IMinutiaMatcher {     public override double Match(MyFeature query, MyFeature template)     {         List matchingMtiae;         return Match(query, template, out matchingMtiae);     }     public double Match(object query, object template, out List matchingMtiae)     {         // Place here your code to match fingerprints     } } Интегрированные встроенные алгоритмы в фреймворке Пользователям не нужно изменять фреймворк для интеграции обычных алгоритмов, так как Рефлекция загружает динамически, во время выполнения программы. В этом случае пользователи должны добавить новые алгоритмы к их собственным обычным сборкам. Для того, чтобы использовать существующие алгоритмы сравнения в фреймворке, первое, что необходимо сделать, создать поставщик ресурсов. Поставщик ресурсов позволяет сохранять (полученный) в (выходной) файл ресурсы, связанные с отпечатками пальцев. К примеру, предположим, что пользователи хотят интегрировать SourceAFIS SDK (http://www.sourceafis.org/) в фреймворк, следующая функция обеспечения может использоваться как: public class SourceAFISFeatureProvider : ResourceProvider {     protected override Person Extract(string fingerprint, ResourceRepository repository)     {         Fingerprint fp = new Fingerprint();         fp.AsBitmap = imageProvider.GetResource(fingerprint, repository);         Person person = new Person();         person.Fingerprints.Add(fp);         Afis.Extract(person);         return person;     }     public override string GetSignature()     {         return string.Format("sAFIS");     }     public override bool IsResourcePersistent()     {         return true;     }     private static AfisEngine Afis = new AfisEngine(); } А сейчас алгоритм сравнения отпечатков может быть записан в следующие классы: public class SourceAFISMatcher : Matcher {     public override double Match(Person query, Person template)     {         return Afis.Verify(query, template);     }     private static AfisEngine Afis = new AfisEngine(); } Результаты эксперимента Мы выполнили обширный эксперимент с алгоритмами сравнения отпечатков пальцев, пользуясь фреймворком. Выводы В данной статье продемонстрировали фреймворк в C# для распознавания отпечатков пальцев. Мы коротко объяснили, как выполнить опыты по распознаванию отпечатков и как интегрировать собственные алгоритмы в фреймворк. Мы предоставили несколько алгоритмов сравнения отпечатков пальцев и алгоритмов извлечения признаков, с помощью которых вы можете не только делать эксперименты, но и создать собственные приложения. Мы показали исходные коды всех алгоритмов, поэтому пользователь может использовать любую часть кода так же, как и любой компонент программного обеспечения. Источник: http://www.codeproject.com/Articles/97590/A-Framework-in-C-for-Fingerprint-Verification
Модуль Asyncio Python

Автор: Олексій Орленко

Введение Мы продолжаем цикл статей об асинхронном программировании с использованием сопрограмм в Python. В предыдущей статье мы рассмотрели реализацию сопрограмм при помощи генераторов в Python 2.5 и выше, в этой же познакомимся с той инфраструктурой, которая построена на основе них в Python 3. В Python 3.4 был включён модуль asyncio, который, на самом деле, был доступен в виде отдельного пакета на PyPI ещё для Python 3.3. Этот модуль предоставляет всю необходимую инфраструктуру для написания однопоточного конкурентного кода с использованием сопрограмм неблокирующего ввода-вывода, мультиплексирования ввода-вывода через сокеты и другие ресурсы, запуска сетевых клиентов и серверов и т.д. Его возможности: цикл событий с разными его реализациями, оптимизированными для различных операционных систем; абстракции «транспорта» и «протокола» (подобные тем, что используются в фреймворке Twisted); поддержка TCP, UDP, SSL, конвейеров UNIX-процессов, отложенных вызовов; адаптированный для использования с циклом событий класс Future, который представляет ещё не вычисленный результат асинхронной функции; сопрограммы и задачи, основанные на основе генераторов; поддержка отмены Future и сопрограмм; примитивы синхронизации для использования с сопрограммами; возможность запуска задач в пуле потоков либо пуле процессов, что позволяет даже взаимодействовать с библиотеками, которые совершают блокирующий ввод-вывод. В основе модуля asyncio лежит цикл событий (event loop). Он отвечает за: создание задач из сопрограмм и Future и их выполнение; регистрацию, исполнение и отмену отложенных вызовов; создание клиентских и серверных транспортов для различных видов коммуникации; запуск подпроцессов и связи их с транспортами для взаимодействия со внешним процессом; делегирование медленных вызовов обычных функций пулу потоков или пулу процессов. Сопрограммы в asyncio – это генераторы, которые отвечают определённым требованиям. Ко всем сопрограммам должен быть применён декоратор @asyncio.coroutine. Действия, которые поддерживают сопрограммы asyncio: result = yield from future – приостановка выполнения сопрограммы до получения future значения и присвоение этого значения переменной result (если future отменён, возникает исключение CancelledError); result = yield from coroutine – ожидание завершения работы другой сопрограммы и получение её результата; return result – возврат значения в сопрограмму, ожидающую данную; raise exception – выброс исключения для обработки его ожидающей сопрограммой (если оно не обработано в текущей). Рассмотрим пример двух сопрограмм, одна из которых вызывает другую, производящую какие-то затратные вычисления (на самом деле, для простоты примера она будет просто приостанавливать своё выполнение на одну секунду и возвращать квадрат числа). import asyncio @asyncio.coroutine def time_consuming_computation(x):     print('Computing {0} ** 2...'.format(x))     yield from asyncio.sleep(1)     return x ** 2 @asyncio.coroutine def process_data(x):     result = yield from time_consuming_computation(x)     print('{0} ** 2 = {1}'.format(x, result)) if __name__ == '__main__':     loop = asyncio.get_event_loop()     loop.run_until_complete(process_data(238))     loop.close() Функция get_event_loop модуля asyncio возвращает объект цикла событий, и мы используем его метод run_until_complete для запуска сопрограммы. Какое же в данном случае преимущество перед обыкновенными функциями? Во время работы сопрограммы asyncio.sleep выполнение программы не блокируется, и, если бы у нас были другие запланированные для выполнения задачи, они могли бы в это время выполняться в том же самом потоке. Несмотря на то, что данные сопрограммы выглядят как обычный последовательный код, на самом деле отдельные их части исполняются асинхронно. На схеме выше показано, в каком порядке исполняется код из примера. Можем переписать созданный ранее пример при помощи модуля asyncio. import asyncio import random import time @asyncio.coroutine def consume():     """Сопрограмма обработки данных"""     running_sum = 0     count = 0     while True:         data = yield from produce()         running_sum += data         count += 1         print('Got data: {}\nTotal count: {}\nAverage: {}\n'.format(             data, count, running_sum / count)) @asyncio.coroutine def produce():     """Сопрограмма выдачи данных."""     yield from asyncio.sleep(0.5)     data = random.randint(0, 100)     return data def main():     loop = asyncio.get_event_loop()     loop.run_until_complete(consume())     loop.close() if __name__ == '__main__':     main()   Обратите внимание, что пришлось изменить логику его работы: теперь основной является сопрограмма consumer, а producer выдаёт одну порцию данных. Причиной этого является рассмотренные ранее ограничения, накладываемые на сопрограммы asyncio, которые логично следуют из основного предназначения данного модуля: совершение асинхронного ввода-вывода. В более реальном примере аналог сопрограммы producer мог бы, например, получать данные с внешнего сервера или базы данных.
Notification success