FreePBX 13 пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ
Слишком длинный поисковый запрос.
По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие
наши статьи:
Все мы любим компьютеры. Они могут делать столько удивительных вещей. За пару десятилетий компьютеры произвели самую настоящую революцию почти во всех аспектах человеческой жизни.
Они могут справляться с задачами различной степени сложности, просто переворачивая нули и единицы. Просто удивительно, как такое простое действие может привести к такому уровню сложности.
Но я уверен, что вы все знаете, что такой сложности нельзя добиться (практически нельзя) простым случайным переворачиванием чисел. Но за этим стоит определенные логические рассуждения. Есть правила, которые определяют, как это все должно происходить. В данной статье мы обсудим эти правила и увидим, как они управляют «мышлением» компьютера.
Что такое булева алгебра?
Это правила, о которых я упоминал выше, описываются некой областью математики, называемой булевой алгеброй.
В своей книге 1854 года британский математик Джордж Буль предложил использовать систематический набор правил для работы со значениями истинности. Эти правила положили математическую основу для работы с логическими высказываниями. А эти основы привели к развитию булевой алгебры.
Для того, чтобы понять, что из себя представляет булева алгебра, сначала мы должны понять сходства и различия между ней и другими формами алгебры.
Алгебра в целом занимается изучением математических символов и операций, которые можно выполнять над этими символами.
Эти символы сами по себе ничего не значат. Они обозначают некую величину. Именно эти величины и придают ценность этим символам, и именно с этими величинами и выполняются операции.
Булева алгебра также имеет дело с символами и правилами, позволяющими выполнять различные операции над этими символами. Разница заключается в том, что эти символы что-то значат.
В случае обычной алгебры символы обозначают действительные числа. А в булевой алгебре они обозначают значения истинности.
На рисунке ниже представлен весь набор действительных чисел. Набор действительных чисел включает натуральные числа (1, 2, 3, 4, …), положительные целые числа (все натуральные числа и 0), целые числа (…, -2, -1, 0, 1, 2, 3, …) и т.д. Обычная алгебра имеет дело со всем этим набором чисел.
Для сравнения, значения истинности состоят из набора, который включает в себя только два значения: True и False. Здесь я хотел бы отметить, что мы можем использовать любые другие символы для обозначения этих значений.
Например, в информатике, как правило, эти значения обозначают через 0 и 1 (0 используется в качестве False, 1 – в качестве True).
Вы также можете сделать это более оригинальным способом, обозначая значения истинности какими-то другими символами, например, кошки и собаки или бананы и апельсины.
Суть здесь в том, что смысл этих значений останется неизменным, как бы вы их не обозначили. Но убедитесь, что вы не меняете символы в процессе выполнения операций.
Теперь вопрос в том, что если (True и False), (0 и 1) – это просто обозначения, то что же они пытаются обозначить?
Смысл, лежащий в основе значений истинности, исходит из области логики, где значения истинности используются для того, чтобы определить, является ли высказывание «Истинным» (True) или «Ложным» (False). Здесь значения истинности обозначают соответствие высказывания истине, то есть показывают, является ли высказывание истинным или ложным.
Высказывание – это просто некоторое утверждение, что-то вроде «Все кошки милые».
Если приведенное выше высказывание верно, то мы присваиваем ему значение истинности «Истина» (True) или «1», в противном случае мы присваиваем ему значение истинности «Ложь» (False) или «0».
В цифровой электронике значения истинности используются для обозначения состояний электронных схем «включено» и «выключено». Подробнее об этом мы поговорим позже в этой же статье.
Логические операции и таблицы истинности
Как и в обычной алгебре, в булевой алгебре также можно применять операции к значениям для получения некоторых результатов. Однако эти операции не похожи на операции в обычной алгебре, поскольку, как мы уже упоминали ранее, булева алгебра работает со значениями истинности, а не с действительными числами.
В булевой алгебре есть три основные операции.
OR: OR или "ИЛИ", также известная как дизъюнкция. Эта операция выполняется над двумя логическими переменными. Результатом операции OR будет 0, если оба операнда равны 0, иначе будет 1.
Для того, чтобы более наглядно продемонстрировать принцип работы этой операции, визуализируем ее с помощью таблицы истинности.
Таблицы истинности дают нам хорошее представление о том, как работают логические операции. Также это удобный инструмент для выполнения логических операций.
Операция OR:
Переменная 1
Переменная 2
Результат
0
0
0
0
1
1
1
0
1
1
1
1
AND: AND или "И", также известная как конъюнкция. Эта операция выполняется над двумя логическими переменными. Результатом операции AND будет 1, если оба операнда равны 1, иначе будет 0. Таблица истинности выглядит следующим образом.
Операция AND:
Переменная 1
Переменная 2
Результат
0
0
0
0
1
0
1
0
0
1
1
1
NOT: NOT или "НЕ", также известное как отрицание. Эта операция выполняется только над одной переменной. Если значение переменной равно 1, то результатом этой операции будет 0, и наоборот, если значение переменной равно 0, то результатом операции будет 1.
Операция NOT:
Переменная 1
Результат
0
1
1
0
Булева алгебра и цифровые схемы
Булева алгебра после своего появления очень долго оставалась одним из тех понятий в математике, которые не имели какого-то значительного практического применения.
В 1930-х годах Клод Шеннон, американский математик, обнаружил, что булеву алгебру можно использовать в схемах, где двоичные переменные могут обозначать сигналы «низкого» и «высокого» напряжения или состояния «включено» и «выключено».
Эта простая идея создания схем с помощью булевой алгебры привела к развитию цифровой электроники, которая внесла большой вклад в разработку схем для компьютеров.
Цифровые схемы реализуют булеву алгебру при помощи логических элементов – схем, обозначающих логическую операцию. Например, элемент OR будет обозначать операцию OR. То же самое относится и к элементам AND и NOT.
Наряду с основными логическими элементами существуют и логические элементы, которые можно создать путем комбинирования основных логических элементов.
NAND: элемент NAND, или "И-НЕ", образован комбинацией элементов NOT и AND. Элемент NAND дает на выходе 0, если на обоих входах 1, в противном случае – 1.
Элемент NAND обладает свойством функциональной полноты. Это означает, что любая логическая функция может быть реализована только с помощью элементов NAND.
Элемент NAND:
Вход 1
Вход 2
Результат
0
0
1
0
1
1
1
0
1
1
1
0
NOR: элемент NOR, или "ИЛИ-НЕ", образован комбинацией элементов NOT и OR. Элемент NOR дает на выходе 1, если на обоих входах 0, в противном случае – 0.
Элемент NOR, как и элемент NAND, обладает свойством функциональной полноты. Это означает, что любая логическая функция может быть реализована только с помощью элементов NOR.
Элемент NOR:
Вход 1
Вход 2
Результат
0
0
1
0
1
0
1
0
0
1
1
0
Большинство цифровых схем построены с использованием элементов NAND и NOR из-за их функциональной полноты, а также из-за простоты изготовления.
Помимо элементов, рассмотренных выше, существуют также особые элементы, которые служат для определенных целей. Вот они:
XOR: элемент XOR, или "исключающее ИЛИ", - это особый тип логических элементов, который дает на выходе 0, если оба входа равны 0 или 1, в противном случае – 1.
Элемент XOR:
Вход 1
Вход 2
Результат
0
0
0
0
1
1
1
0
1
1
1
0
XNOR: элемент XNOR, или "исключающее ИЛИ-НЕ", - это особый тип логических элементов, который дает на выходе 1, когда оба входа равны 0 или 1, в противном случае – 0.
Элемент XNOR:
Вход 1
Вход 2
Результат
0
0
1
0
1
0
1
0
0
1
1
1
Заключение
Итак, на этом мы можем закончить обсуждение булевой алгебры. Надеюсь, что к текущему моменту у вас сложилась неплохая картина того, что же такое булева алгебра. Это, конечно, далеко не все, что вам следует знать о булевой алгебре. В ней есть множество понятий и деталей, которые мы не обсудили в данной статье.
Баги и ошибки неизбежны в программировании. Тем не менее они могут раздражать и вызывать разочарование в работе. Предлагаем разобраться, что такое try / catch в JavaScript.
Что такое блок try/catch в JavaScript?
Блок try/catch в JavaScript используется для обработки ошибок. Он помогает избежать прерывание кода из-за ошибок в вашем скрипте.
Хотя это может показаться чем-то, что можно легко реализовать с помощью оператора if, try/catch предоставляет много преимуществ, которые выходят за рамки возможностей if/else, некоторые из которых мы рассмотрим ниже.
Оператор try позволяет проверить блок кода на наличие ошибок.
Оператор catch позволяет обработать эту ошибку. Например:
Вот как строится конструкция try/catch. Вы помещаете код в блок try, и если возникает ошибка, JavaScript передает управление оператору catch, который выполняет указанные действия. В данном случае он выводит ошибку в виде оповещения.
Все ошибки JavaScript на самом деле являются объектами, которые содержат два свойства: имя (например, Error, SyntaxError и т. д.) и само сообщение об ошибке. Поэтому, когда мы выводим e, мы получаем что-то вроде ReferenceError: getData is not defined.
Как и любой другой объект в JavaScript, вы можете решать, как получить значения по-разному, например, e.name (ReferenceError) и e.message (getData is not defined).
Но на самом деле это не отличается от того, что делает JavaScript. Хотя JavaScript уважает вас достаточно, чтобы записать ошибку в консоль, а не показывать оповещение всему миру.
Как использовать операторы try/catch
Оператор throw
Одно из преимуществ try/catch - это возможность отображать свои собственные пользовательские ошибки. Это называется throw error.
В ситуациях, когда вы не хотите видеть те ошибки, которые отображает JavaScript, вы можете бросить свою ошибку (исключение) с помощью оператора throw. Эта ошибка может быть строкой, булевым значением или объектом. И если возникает ошибка, оператор catch отобразит ту ошибку, которую вы выбросили.
Здорово, не правда ли? Но мы можем пойти дальше, создавая ошибку с помощью конструкторов ошибок JavaScript.
JavaScript в основном классифицирует ошибки на шесть групп:
EvalError - ошибка, произошедшая в функции eval.
RangeError - число вне диапазона, например, 1.toPrecision(500). Метод toPrecision дает числам десятичное значение, например, 1.000, и число не может иметь 500 таких значений.
ReferenceError - использование переменной, которая не была объявлена.
SyntaxError - ошибка синтаксиса при выполнении кода.
TypeError - использование значения, выходящего за пределы ожидаемых типов, например, 1.toUpperCase().
URIError - ошибка, если используются незаконные символы в функции URI.
Таким образом, мы можем легко выбросить ошибку, например, throw new Error("Привет"). В этом случае имя ошибки будет Error, а сообщение — Привет. Вы также можете создать свой собственный конструктор ошибки, например:
И вы можете использовать это везде с throw new CustomError("данные не определены").
Проверим конструкцию try/catch. Рассмотрим следующий пример:
Но когда вы попробуете это выполнить, даже с использованием оператора try, это все равно не сработает. Это потому, что в JavaScript существуют два основных типа ошибок (то, что я описал выше — синтаксическая ошибка и так далее — на самом деле не являются типами ошибок. Вы можете назвать их примерами ошибок): ошибки времени разбора (parse-time errors) и ошибки времени выполнения (runtime errors) или исключения.
Ошибки времени разбора — это ошибки, которые возникают в коде, когда движок не понимает код.
Например, в приведенном выше коде, JavaScript не понимает, что вы имеете в виду под {{}}, и из-за этого ваш try/catch здесь бесполезен (он не сработает).
С другой стороны, ошибки времени выполнения — это ошибки, которые возникают в корректном коде, и это именно те ошибки, которые try/catch сможет обработать.
Приведенный выше код является корректным, и try/catch корректно обработает ошибку.
Оператор finally
Оператор finally действует как нейтральная зона, базовая точка или финальная стадия для блока try/catch. С помощью finally вы говорите, что, независимо от того, что произойдет в блоке try/catch (ошибка или отсутствие ошибки), код в блоке finally должен выполниться. Например:
Вложенные блоки try
Вы также можете вкладывать блоки try, но, как и любое другое вложение в JavaScript (например, if, for и так далее), это может привести к громоздкости и ухудшению читаемости кода, поэтому я не рекомендую это делать. Но это только мое мнение.
Вложение блоков try дает вам преимущество использования одного блока catch для нескольких блоков try. Хотя вы можете написать блок catch для каждого try отдельно, вот пример:
В этом случае не будет ошибки во внешнем блоке try, так как с ним все в порядке. Ошибка возникает во внутреннем блоке try, и она уже обработана своим собственным блоком catch. Рассмотрим следующий пример:
Этот код работает немного иначе: ошибка возникает во внутреннем блоке try, который не содержит catch, но вместо этого имеет блок finally.
Обратите внимание, что блок try/catch можно записать тремя разными способами: try...catch, try...finally, try...catch...finally. Однако ошибка выбрасывается из внутреннего блока try.
Блок finally для этого внутреннего try выполнится в любом случае, потому что, как мы уже говорили, он работает, что бы ни произошло в блоке try/catch. И хотя во внешнем блоке try нет ошибки, управление все равно передается его блоку catch для регистрации ошибки. Более того, используется ошибка, созданная во внутреннем блоке try, потому что она произошла именно там.
Если бы мы создали ошибку для внешнего блока try, она все равно бы отобразила внутреннюю ошибку, если только внутренняя не поймает свою собственную ошибку.
Вы можете поэкспериментировать с кодом ниже, закомментировав внутренний блок catch.
Повторное выбрасывание ошибки (Rethrow Error)
Оператор catch ловит все ошибки, которые попадают в него, и иногда нам это не нужно. Например:
Предположим на секунду, что введенное число будет меньше 5 (цель использования "use strict" — указать, что код должен выполняться в строгом режиме). В строгом режиме, например, нельзя использовать необъявленные переменные.
Я хочу, чтобы оператор try выбросил ошибку "y не меньше 5", когда значение y больше 5, что маловероятно. Ошибка должна быть связана с тем, что y не меньше..., а не с тем, что y не определена.
В таких ситуациях вы можете проверить тип ошибки, и если это не та ошибка, которую вы хотите, повторно выбросить её:
Это просто повторно выбросит ошибку для другого оператора try или остановит выполнение скрипта. Это полезно, когда вы хотите отслеживать только определенный тип ошибок, а остальные, возникшие из-за невнимательности, должны остановить выполнение кода.
В сегодняшней статье расскажем про настройку IVR (Interactive Voice Response) стандартными способами Asterisk, без использования графической оболочки FreePBX.
Аббревиатура IVR описывает систему, в которой вызывающий абонент, по средствам кнопок на телефоне осуществляет навигацию в голосовом меню и соединяется с нужным отделом, сотрудником и службой. В масштабах крупного "Enterprise", конечно, IVR описывает гораздо более сложные системы, где используются различные технологии интеграции. Но мы рассмотрим простейший вариант.
Про настройку IVR через графический интерфейс FreePBX, читайте в нашей статье.
Немного теории
Перед тем как создать простейший пример IVR, необходимо разобраться во внутренних приложениях, которыми оперирует Asterisk.
Приложение Background() проигрывает звуковую запись и в то же время слушает входящие сигналы DTMF (Dual-Tone Multi-Frequency). Система, тем временем, пытается найти совпадения введённых цифр DTMF и внутреннего номера (extension) в текущем контексте дайл-плана, если совпадение есть, то Asterisk отправит вызов на найденный номер.
Приложение WaitExten() необходимо, если вы хотите заставить Asterisk подождать какое-то время после того, как он воспроизведет звуковую запись. Параметры, задающиеся в WaitExten() - это количество секунд, которые система будет ждать, прежде чем разрешит абоненту совершить набор внутреннего номера, например – WaitExten(10).
Приложение Goto() позволяет переходить с одной позиции в дайл-плане на другую – это может быть контекст (context), внутренний номер (extension) и приоритет (priority).
Конфигурация
Теперь мы можем создать простейший пример голосового меню, используя вышеупомянутые приложения. Как правило, IVR создаётся в новом контексте, таким образом оставаясь независимым от остальных настроенных extension’ов в дайл-плане.
Основная запись, содержащая сценарий голосового меню будет следующей: "Здравствуйте вы позвонили в компанию %companyname%. Для того, чтобы соединиться с отделом поддержки нажмите 1. Для того, чтобы соединиться с отделом продаж нажмите 2. Если Вы знаете внутренний номер абонента, наберите его в тональном режиме".
Настройку IVR проводим в файле extensions.conf и добавляем туда следующую запись:
[ivr-example]
exten => s,1,Answer(500)
same => n(loop),Background(Main_IVR_record)
exten => 1,1,Goto(3445,s,1)
#Переход в контекст отдела поддержки по нажатию кнопки 1. 3444 – Ринг группа отдела поддержки.
exten => 2,1,Goto(3444,s,1)
#Переход в контекст отдела продаж нажатию кнопки 2. 3445 – Ринг группа отдела продаж.
exten => _XXX,1,Dial(SIP/${EXTEN}@Asterisk)
#Набор внутреннего номера сотрудника
Теперь, для инициализации IVR, остается только вызвать контекст [ivr-example].
