Ну это конечно вообще жесть, с WCE я бы еще мог согласится, но XP — точно пербор ivanhoe
Незнаю, незнаю. Как то мне не очень часто приходится разбирать банкоматы, а по одному только виду морды приложения — сказать что там иногда бывает трудно.
цитата: нет проблем с драйверами и API для специфической периферии: сканеры штрихкодов, счетчики купюр и пр. — под винду они есть всегда
AzikAtom написано 04.09.2010 08:52 |
IMHO, банкоматы не спешат идти на windows. Банкомат (довольно старый), с которым я когда-то работал, имел на борту OS/2. Все-таки, банкомат и терминал для приема денег на телефон имеют разные уровни безопасности. |
Rudolf написано 06.09.2010 16:33 |
vertur WCE я бы еще мог согласится, но XP — точно пербор А я бы наоборот на ATM поставил бы XP. Я с WinCE достаточно повозился, не на мобилках, так что ну ее нафик, сырая как была, так и померла сырой. Лучше уж ХР embedded или даже полноценная XP, железо позвляет теперь. Это будет намного дешевле, учитывая то, что фичи добавлять будет легче и быстрее, чем в WinCE, где постоянно могут возникнуть тормоза из-за отсутствия дров, кривости оных или отсутствия нужных системных утилит. Одна дефрагментация кривая в WinCE чего стоит. Да, про .NET Compact FrameWork чуть не забыл. Тоже гадость по сравнению с нормальным 2.0, например. Индусами все порезано, причем порезано по индусской логике. |
Приёмы и хитрости в терминале GNU/Linux
цитата (Rudolf): Одна дефрагментация кривая в WinCE чего стоит.
На сколько я помню, дефрагментации родной вообще в WCE нету. Да и ненужно оно там.
цитата: Я с WinCE достаточно повозился, не на мобилках, так что ну ее нафик, сырая как была, так и померла сырой. учитывая то, что фичи добавлять будет легче и быстрее, чем в WinCE, где постоянно могут возникнуть тормоза из-за отсутствия дров, кривости оных или отсутствия нужных системных утилит.
Кто вам такое сказал что она померла ? Как была так и есть и дохнуть совсем не собирается. Да и ядро более нормальное стало чем было. А про фичи вообще — смех, берете платформ билдер и собираете себе образ какой надо.
Про индусов — конечно верно подмечено, но это касается того что они сами заливают на железки — да там иногда жесть бывает, кстати корейцы и китаезы — вообще трендец что там вытворяют. Но кто вам мешает свой образ пересобрать и залить на железку ?
цитата: Да, про .NET Compact FrameWork чуть не забыл. Тоже гадость по сравнению с нормальным 2.0, например. Индусами все порезано, причем порезано по индусской логике.
Python в Kali Linux — 3 способа КАК написать программу
Источник: poisk2.ru
Как мы когда-то писали ПО для терминала самообслуживания
2013-10-28 в 21:19, admin , рубрики: платежный терминал, разработка, метки: платежный терминал
Не так давно мне на просторах Хабра попалась статья-начало цикла о терминалах самообслуживания, в которой было рассказано из каких «железяк» может состоять терминал. Что и напомнило мне, что когда-то давно некоторая группа людей, в которую входил и я, пыталась покорить вселенную своим стартапом, как раз связанным с терминалами и т. д. Но вселенная посмотрела на нас, почесала где-то в области затылка и поняла, что ей и без завоевателей не плохо живется, т. е. как вы поняли, стартап не взлетел. Но некоторый опыт-то остался. Как раз про терминальный софт я и хотел изложить свое мнение. Может оно и будет полезным иным покорителям вселенной на этом же поприще, увидя в описанном для себя какие-то паттерны или антипаттерны.
Терминал — это по сути самый обычный компьютер в нестандартном корпусе и с расширенным набором внешних устройств. Этот самый расширенный набор и определяет для какой услуги терминал предназначен.
Каков мог бы быть софт для такой железяки?
Предлагаю такой набор составляющих:
- Некоторая среда, в которой будут работать все компоненты терминального ПО (компонентная модель; framework; система плагинов).
- Компоненты-обертки вокруг драйверов устройств.
- Компонент обновления.
- Компонент настройки.
- Компоненты бизнес-логики.
- Компоненты пользовательского интерфейса.
- Вспомогательные / сервисные компоненты.
Если немного укрупнить части системы, то можно выделить всего две части: компонентная модель и компоненты системы, исполняемые в этой самой модели.
Компонентная модель
Не знаю для кого как, но для меня это самая интересная часть. Я долго себя обманывал, что мне больше всего интересно писать бизнес-логику, но оказалось это не так. Интереснее всего для меня — это «клей», т.е. как раз всяческие связующие вещи для систем, они же компонентные модели и вспомогательные библиотеки общего использования, т.е. как раз то, к чему программист ближе всего. А чтобы любить бизнес-логику надо, как минимум, обладать хоть какой-то экспертизой в этом самом бизнесе.
Как вы и на каких принципах построите компонентную модель это ваше дело. Можно построить взаимодействие компонент на основе асинхронной посылки событий друг другу через нечто. Можно все сделать на интерфейсах (в C++ терминах — это структурах с чисто виртуальными методами) и какую-нибудь модель их добывания, типа (сейчас скажу страшное слово, от которого многие плюются) COM.
Или еще что-то. У всего будут и плюсы и минусы. Компоненты могут жить в рамках одного процесса или в рамках нескольких; так же есть свои нюансы. А можно забить на все эти архитектурные изыски, на декомпозицию и т.д., все свалить в один модуль или (учу плохому) прибегнуть к пластилиновой архитектуре и быстрее выползать на рынок.
Теперь немного поподробнее о каждом из подходов с моей точки зрения (буду рад вашу видеть в комментариях).
Асинхронно посылаемые события против интерфейсов
Для меня, с практической точки зрения написания бизнес-логики как раз терминалов самообслуживания, модель на интерфейсах куда удобнее модели, в которой все обмениваются между собой методом посылки событий. Почему? Рассмотрим такой казалось бы простой момент: дошли мы в какой-то покупке до внесения денег.
Для этого, предположим, надо послать «купюрнику» сигнал о начале приема денег, дать некоторый промежуток времени на прием денег (что клиент, просто не пропадет, после первых 10 рублей из 10000 и, плюнув на все, не уйдет), после которого либо провести транзакцию, либо откат логики в какое-то начальное состояние и т.д. Тут, включая параноидальное мышление , есть некоторые ситуации, за которыми надо следить: событие, посланное от купюрника пришло в бизнес-логику за некоторый промежуток времени, а не болтается в очереди событий, пока обрабатываются какие-то «тяжелые» события или компонент отвалился вообще.
Получается в бизнес-логике появляются всякие таймеры на ожидания разных событий и подтверждений. Не буду спорить, что асинхронные модели — это хорошо, но, по моему устойчивому мнению, больше в серверной части. В клиентской можно плюшками асинхронности и пожертвовать в пользу упрощения. Работая «на интерфейсах» (с блокирующими вызовами и некоторыми еще плюшками) все упрощается, а некоторые внештатные ситуации можно решить по иному.
Что есть компоненты и где они должны жить?
Компонент — это некоторая единица, предоставляющая некоторый интерфейс. Это может быть обертка драйвера устройства, бизнес-логика и т.д. Физически компонент может обитать в динамической библиотеке (как и несколько компонент в рамках одной динамической библиотеки) и в рамках процесса, так и в разных исполняемых модулях и процессах, или иметь гетерогенную модель: компоненты в динамических библиотеках, объединяемые разными исполняемыми модулями и исполняемые в отдельных процессах-компонентных моделях (мда, «И тут Остапа понесло» (с) ).
Преимущества раскладывания компонент по динамическим библиотекам в том, что можно сделать некоторый конструктор и формировать наборы компонентов. Можно делать пакет для платежного терминала с определенным набором платежей, для терминала электронной очереди (например банка), сделать «музыкальный автомат» (в кафе сунул купюрку, послушал любимую песню. Тут конечно может быть диверсия: кто-то 2 августа закажет «Голубую луну» и быстро скроется из питейного заведения, а автомат весьма незамысловатыми действиями коллективного труда будет разобран на кварки, но это уже вопрос бизнес-логики управления контентом). Кроме того, при наличии компонент, систему на терминалах можно обновлять частями; как один из положительных моментов этого решения — снижение нагрузки на серверную часть, отвечающую за раздачу обновлений (при большой сети автоматов это уже может быть немаловажно).
Все хорошо складывается с раскладыванием компонент по динамическим библиотекам, и, казалось бы, что раскладка компонент по исполняемым модулям и выполнение в разных процессах не нужно. Вынесение компонент в отдельные исполняемые модули и, как следствие, выполнение в других процессах — это как минимум возня с IPC. Иногда пригождается.
Вы не сталкивались с проблемой, когда несколько библиотек конфликтуют в одном модуле при сборке или куда хуже при исполнении? К сожалению, такое бывает. Тут разнесение на разные исполняемые модули и помогает. Второй момент немного параноидальный: вы не хотите, чтобы какой-то сторонний закрытый код, поставляемый в виде библиотеки (например, драйвер одного из устройств) имел доступ к адресному пространству вашего процесса, так как он, например, по непонятным причинам иногда «роняет процесс», вот еще кандидат на вынесение в отдельный процесс. Это множество ситуаций можно расширять, оно не будет никогда пустым, но его элементы — это исключительные редкие ситуации.
Так некоторым количеством букв я реабилитировал необходимость существования некоторой среды-компонентной модели. Если вы не планируете большую гибкую систему, то вполне на первое время все можно делать в рамках одного модуля и процесса. Только не скатывайтесь к пластилиновой архитектуре.
Компоненты-обертки вокруг драйверов устройств
Тут особо не пофилософствуешь. Задача простая, решения могут быть сложными… Задача: адаптировать интерфейс работы с устройствами к некоторым внутренним интерфейсам разрабатываемого ПО, которым, например, могут пользоваться модули бизнес-логики. Сложность решения заключается в изучении документации на соответствующее устройство или в поиске таковой перед тем как что-то изучать. Далее все просто — или писать обертку над API предоставленного драйвера, или самому формировать загадочные последовательности битов, описанные в спецификации к устройству и слать их в соответствующий порт, к которому подключено устройство.
Компонент обновления (Updater)
Система обновления ПО терминала может быть не так проста как хотелось бы. Если нет никакой компонентной архитектуры, а обновлять надо всего один исполняемый модуль и некоторый медиаконтент, то проблем меньше. А если еще есть некоторый временной интервал в сутках, когда система может полностью «заняться собой» и никого не обслуживать, то все совсем просто.
Если у вас компонентная модель с кучей разного рода компонент, то тут шире пространство для размышления о построении модуля обновлений. Несомненный плюс — это то, что не надо обновлять все, а только те, которые изменились. За такую гибкость, как и за все в этой жизни, придется заплатить. В данном случае большим контролем за тем, чтобы обновляемые модули могли работать с версиями тех, которые не были обновлены.
Обновление без остановки системы. Скачивается новая версия модуля, старый отгружается из памяти, новый загружается и система продолжает работать. Светлое будущее, коммунизм, и Ленин такой молодой, и октябрь у нас впереди. Утопия в реальности… Так как большая сложность разработки компонент для такого механизма обновления.
По моему мнению, с которым вы, конечно, можете и не согласиться, при обновлении система должна завершить правильно выполняемую операцию, полностью остановить работу, произвести обновление модулей или их части и начать работу с некоторой базовой точки, например, с экрана приветствия. Такое упрощение сильно упростит разработку компонент. Можно сделать небольшое исключение: не останавливать систему при обновлении некритического контента.
В идеале на систему обновления можно возложить и начальную установку ПО. Т.е. дилер приобретает терминал, на котором кроме среды исполнения, системы обновления и компонента настройки нет ничего, задает некоторые базовые параметры (например: адрес сервера и некоторый идентификационный номер), система обновления скачивает все, что положено данному дилеру согласно его набору услуг, на который был заключен договор с поставщиком, а идентификационный номер как раз и определит необходимый пакет ПО.
Компонент настройки
Некоторый компонент, который даже на «пустом» терминале будет иметь пользовательский интерфейс (может даже написанный на родном API ОС или с использованием таких библиотек как Qt) для задания как минимум начальных параметров, о которых было написано выше. Компоненты же, в свою очередь, могут иметь некоторый программный интерфейс, с помощью которого компонент настройки может получать от них списки настраиваемых параметров, допустимые, текущие значения и значения по умолчанию для визуализации и изменения. Так же, помимо пользовательского интерфейса, данный модуль может работать с конфигурационными файлами. Можно декомпозировать и декомпозировать систему и вынести хранение всех заданных параметров в отдельную базу и предоставить соответствующий программный интерфейс, но, немного покривя душой, эту функциональность можно совместить и с компонентом настройки.
Компонент бизнес логики
В этих компонентах размещаются все сценарии оказываемых услуг терминалами самообслуживания. Таких компонент может быть множество, так как один и тот же терминал может производить и оплату сотовой связи и билеты в цирк теоретически продавать. Все пихать в один компонент логики не стоит.
Предположим изначально работает только логика экрана приветствия, в функции которой входит дать пользователю выбор необходимой ему услуги. После выбора услуги передается управление логике оказания данной услуги, которая уже как-то взаимодействует с нужными ей устройствами посредством компонент-оберток драйверов (принтер, купюроприемник и прочими), «переключает» экраны согласно заданному сценарию (страницы веб-браузера например), реагирует на активность пользователя. Отсюда можно сделать некоторое заключение, что при обновлении можно поставлять пакеты из модулей бизнес-логики и связанного с ней контента (например, веб-страницы для пользовательского интерфейса).
Дилеру же работа с новой услугой может быть добавлена приходом такого пакета в обновлении, без замены чего-то уже установленного (вот они плюсы компонентности при расширении спектра предоставляемых услуг).
Компоненты пользовательского интерфейса
Эта часть системы для отображения контента и реагирования на действия пользователя.
Терминалы могут быть как с одним экранои, так и с несколькими. Как правило интерактивен только один экран, остальные могут служить для показа рекламы.
Что же использовать для создания пользовательского интерфейса?
Наиболее распространен веб-интерфейс (набор html + картинки), чуть менее flash. Остальные варианты создания пользовательского интерфейса уже куда менее рентабельны.
Популярность html при разработке пользовательского интерфейса в том, что он дает большую скорость разработки, а движки для отображения html относительно легко встраиваются в собственное ПО. Реагировать на действия пользователя можно через какой-нибудь внутренний интерфейс движка, а если таковой не обнаружен или не дает той гибкости, которая нужна разработчику, то можно в своем модуле пользовательского интерфейса построить мини веб-сервер, например, используя libevent, и общение html интерфейса с остальной частью организовать посредством http запросов с уже вашей специфичной обработкой.
Разработка интерфейса на flash так же интересна и дает возможности для создания множества красивых эффектов, но немного хуже встраивается в собственное ПО. Несколько лет назад мне так и не удалось сделать нормальную связку flash ExternalInterface и C++ под linux (под windows все было гораздо лучше с этим вопросом). Как выход из ситуации можно предложить описанное выше решение со встроенным мини веб-сервером.
Html и flash это то, что видит пользователь, но бизнес-логика не должна работать с движками html и flash. За эту часть должен отвечать компонент пользовательского интерфейса, задача которого инкапсулировать всю работу с движками и предоставить бизнес-логике некоторый внутренний программный интерфейс.
Тут есть одна тонкость: отучить разработчиков компонента пользовательского интерфейса и разработчиков html и flash втаскивать хоть какие-то мало мальские куски логики в свою часть. Парадокс, но хоть ладаном окуривай и кадилом среди разработчиков тряси, все равно будут тащить куски логики к себе. Феномен мне пока не понятен.
Все осознают и соглашаются, что UI ничего не должен делать, кроме как посылать события от элементов управления в бизнес-логику и отображать тот контент, на который указала логика, но нет; чуть зазевался и уже прикрутили на нажатие какой-то кнопки переход на некоторый экран, а потом часы отладки нескольких частей команды разработчиков и препирания на тему, что это не в его части ошибка. Желание вбить лом в многослойную архитектуру, пробив все ее слои, для решения маленькой частной проблемы неискоренимо в любой части, не только в UI. Все должна делать логика, а UI только отображать, на что указали и посылать в логику события от элементов управления.
Заключение
Все что описано выше не беспочвенный полет мыслей, а вполне реально разрабатываемая когда-то ранее система. У нас было, можно сказать, все: терминалы, ПО для терминалов, серверная часть. Оставалось не так много с технической стороны, но не взлетело…
В умных книжках о стартапах бывают описаны причины, по которым стартап не взлетает. Есть одна описанная очень интересная причина: опережение идеей времени. Т.е. рынок еще не готов к принятию такого продукта, который выкатывает стартапер и продукт становится невостребованным.
Иногда, смотря на некоторые проекты, видишь какие-то куски того, что пытались сделать несколько лет назад. По этой причине хорошо себя тешить и отвечать другим, что проблема была именно в невостребованности из-за опережения. Но на самом деле это не так и стартапы могут погубить куда более простые причины, например, нечеткость курса при движении к цели, частые перемены в требованиях (хотелках).
«Часто пересаживаемые яблони редко плодоносят». (с) «Менеджер мафии. Руководство для корпоративного Макиавелли».
Всем спасибо за внимание!
Источник: www.pvsm.ru
Торговый робот для QUIK. На каком языке программирования его написать, как протестировать и как установить в торговый терминал
Как и многие другие, я начинал свою работу в качестве трейдера с торгового терминала Metatrader4. И когда у меня созрела необходимость в написании собственных скриптов и советников (торговых роботов), я не мудрствуя лукаво открыл учебник по MQL4 и изучив основы этого языка, через пару часов уже мог состряпать простую программку.
Дальше-больше, после реализации простых скриптов пришло желание запрограммировать более сложные алгоритмы торговли. Возникали, конечно, вопросы, но ответы на них достаточно легко дают Яндекс с Гуглом. В настоящее время существуют столько сайтов и форумов посвящённых данной тематике, что достаточно трудно найти такой вопрос, который остался бы без ответа после более-менее тщательного штудирования интернета.
Для чего я вам все это рассказал? Дело в том, что никакого особого опыта в программировании, кроме школьных уроков информатики у меня до этого не было. А это означает, что для того, чтобы справиться с этим делом вовсе не обязательно быть программистом.
Если же у вас за плечами уже есть какой-либо опыт программирования на любых языках, то данная задача вам покажется элементарной. Уверяю вас, так оно на самом деле и есть, на деле здесь всё оказывается куда проще и стоит только начать, как вы незаметно для себя уже превратитесь в матёрого создателя торговых роботов.
Как написать программу
В QUIK предусмотрена возможность установки двух основных типов программ скриптов и торговых роботов:
- Программ написанных на языке QPILE;
- Программ написанных на языке программирования LUA.
На мой взгляд, наиболее простым вариантом является работа с программами на языке LUA. Область применения данного языка программирования не ограничивается только написанием программ для торговых терминалов, на нём пишут и компьютерные игры, и мобильные приложения, и много чего ещё. Но нас сейчас интересует его использование в контексте написания программ торговых роботов для торгового терминала QUIK. К слову сказать, используемая здесь разновидность данного языка часто именуется QLUA (Q от QUIK).
Программирование на LUA
Описать все особенности и синтаксические конструкции языка в рамках одной этой статьи конечно не получится, впрочем в этом и нет особой необходимости. Как я уже говорил, синтаксис здесь довольно простой и включает в себя все основные команды свойственные любому современному языку программирования. Есть, конечно, некоторые специфические моменты, но все они подробно описаны на многочисленных тематических ресурсах. Например здесь: https://forum.quik.ru/forum10/topic2029/
Я сильно не заморачивался ни синтаксисом, ни изучением языка, а просто сразу начал писать программу. По ходу необходимости, уточнял синтаксис той или иной необходимой мне команды через поисковики. Например запрос типа “оператор для открытия позиции в QLUA” подсказывал мне, что для данной цели необходимо использовать оператор sendTransaction(), а запрос “синтаксис оператора sendTransaction() в LUA” выдавал в первой же позиции результатов поиска сайт содержащий ответ:
На этом сайте вы найдёте синтаксис всех команд языка с конкретными примерами их использования: http://luaq.ru/
А вот здесь вы найдёте полное руководство по азам программирования на LUA: https://lua.org.ru/contents_ru.html
Кроме этого есть ещё масса других ресурсов содержащих исчерпывающую информацию по данной теме.
Где писать программу. Какой редактор использовать?
Прелесть состоит в том, что для написания программ на QLUA можно обойтись штатными средствами Windows, без установки каких-либо специализированных редакторов. Вы можете писать и редактировать программу прямо в текстовом файле.
Для этого сначала создаёте обычный текстовый файл:
Затем сохраняете его изменив расширение с .txt на .lua. Для этого необходимо проделать следующий ряд нехитрых манипуляций:
- В меню текстового документа “Файл” необходимо выбрать пункт “Сохранить как”
- В выпавшем окне сохранения нужно вместо расширения “Текстовый документ” выбрать расширение “Все файлы”
- К названию сохраняемого документа добавить .lua
- Нажать кнопку “Сохранить”
Неудобство данного метода написания состоит в том, что без редактора невозможно скомпилировать файл и проверить его на наличие ошибок. Однако это не так критично, как может показаться на первый взгляд, поскольку наличие ошибок (а также их краткое описание) вам выдаст торговый терминал после того как вы попытаетесь запустить в нем программу.
После этого достаточно будет её отредактировать и запустить вновь. В том случае, если ошибок больше нет, окно “Ошибки выполнения скрипта” останется пустым, а программа начнёт работать (об этом будет свидетельствовать характерный значок “play” перед названием). После того, как заложенный в неё алгоритм отработает, она остановится. Если же она специально зациклена (работает на постоянное отслеживание текущей рыночной ситуации), то остановить её можно будет нажатием на кнопку “Остановить”.
Как протестировать торгового робота
В Метатрейдере с этим делом всё обстоит довольно просто — запускаешь тестер стратегий, выбираешь временной интервал ценовой истории и вперёд. Тестер прогонит через загруженного в него торгового робота весь массив цен из заданного в настройках интервала и выдаст вам график прибыли/убытка которые были бы получены роботом при реальной торговле online. При этом у вас ещё будет возможность оптимизировать настройки тестируемого торгового робота таким образом, чтобы получить наилучший результат (наибольший профит), правда на всё том же ограниченном интервале истории.
В QUIK такого тестера априори не существует. То есть тестировать созданных роботов на истории вы здесь не сможете**, но оно, пожалуй, и к лучшему. Почему к лучшему? Излишняя оптимизация на истории может сыграть с вами злую шутку. Дело в том, что самые замечательные результаты торговли в прошлом никогда не гарантируют вам того же и в будущем.
Часто бывает так, что стратегии “заточенные” (читай — оптимизированные) под определённый интервал времени в прошлом и приносящие на нём стабильно высокий доход, в реальном времени начинают откровенно сливать депозит.
Но не расстраивайтесь, торговых роботов для терминала QUIK вы сможете тестировать в реальном времени. Правда для этого вам потребуется так называемый демо-счёт (вы ведь не хотите, чтобы тестируемый советник принялся сразу же торговать реальными деньгами).
В отличие от метатрейдера в котором и реальные, и учебные счета открываются в одном и том же терминале, в квике для этого нужно установить специальный учебный терминал. По сути своей это тот же QUIK, только данные он берет со специального — учебного сервера (котировки немного отстают по времени от реальных, но в целом повторяют их с достаточной точностью) и для торговли здесь используются виртуальные деньги.
Учебный QWIK можно скачать у любого брокера, желательно у того, через которого вы планируете в дальнейшем торговать. Правда здесь возможны некоторые заморочки связанные с тем, что не всегда учебная версия данного торгового терминала позволяет работать со скриптами LUA.
Если та версия, которую предлагает ваш брокер не поддерживает возможножность установки и запуска LUA-скриптов, то можете установить демку от брокера БКС. Это не реклама, просто у меня стоит такая же и я точно знаю, что данная версия позволяет работать с любыми скриптами и советниками написанными на языке программирования LUA (QLUA).
** По крайней мере чистыми средствами QUIK, без использования какого-либо дополнительного софта.
Как установить LUA-скрипт в торговый терминал
Процесс установки торгового робота (скрипта) одинаков и для учебного, и для реального терминалов. Он довольно прост и выглядит следующим образом:
- Сначала заходите в верхнее меню терминала “Сервисы” и находите там кнопку “LUA-скрипты”:
- После нажатия на неё, перед вами появится уже знакомое вам окно “Доступные скрипты”. Жмём кнопку “Добавить” и в выпавшем окне выбираем созданный вами файл торгового робота или скрипта.
Вот и всё, на этом процесс установки торгового робота закончен. Для того, чтобы он начал работать достаточно выбрать его кликом мышки и нажать кнопку “Запустить”. Если в программе не будет обнаружено ошибок, то она начнёт работать, а иначе выдаст вам соответствующее сообщение (см. выше).
Источник: www.azbukatreydera.ru