По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
Когда мы только начинаем изучать Python, мы закладываем некоторые вредные привычки при написании кода, о которых мы можем даже не подозревать. Вы можете написать код, который сработает сейчас, но может не сработать в будущем, или вы можете использовать какие-то хитрые ходы вместо встроенной функции, которая могла бы облегчить вашу жизнь. У большинства из нас сохранились не одна из тех вредных привычек при программировании на Python, что формируются в период первых месяцев обучения. Отличная новость в том, что вы можете с легкостью искоренить их, прочитав приведенный ниже текст. 1. Использование import * Каждый раз, когда нам становится лень, то возникает соблазн импортировать все необходимое из модуля с помощью from xyz import *. Это не самый лучший подход по многим причинам. Кот несколько из них: Это может оказаться неэффективно: если в модуле очень много объектов, то вам придется долго ждать, пока все импортируется. Это может вызвать конфликт имен переменных: когда вы используете *, то вы понятия не имеете, какие объекты вы импортируете и как они называются. Как же с этим бороться? Импортируйте либо какой-то конкретный объект, либо весь модуль целиком. # Using import * # Bad from math import * print(floor(2.4)) print(ceil(2.4)) print(pi) # Good import math from math import pi print(math.floor(2.4)) print(math.ceil(2.4)) print(pi) 2. Try/except: отсутствие указания исключения в блоке «except» Я очень долго пренебрегал этим. Сложно посчитать, сколько раз Pycharm давал мне понять (этими противными подчеркиваниями), что не нужно использовать «голое» исключение. Это идет в разрез с рекомендациями PEP8. # Try - except # Bad try: driver.find_element(...) except: print("Which exception?") # Good try: driver.find_element(...) except NoSuchElementException: print("It's giving NoSuchElementException") except ElementClickInterceptedException: print("It's giving ElementClickInterceptedException") Проблема «голых» исключений заключается в том, что оно будет перехватывать исключения SystemExit и KeyboardInterrupt, что затрудняет прерывание программы с помощью Control-C. В следующий раз, когда вы будете использовать try/except, укажите исключение в блоке except. 3. Не использовать Numpy для математических вычислений Очень часто мы забываем, что в Python есть множество пакетов, которые могут значительно облегчить нашу жизнь и сделать ее более продуктивной. Одним из таких пакетов является Numpy – пакет для математических вычислений. Numpy может помочь вам вычислять математические операции быстрее, чем циклы for. Допустим, что у нас есть массив random_scores, и мы хотим получить средний балл тех, кто не сдал экзамен (score>>dict_countries.keys() dict_keys(['USA', 'UK', 'Canada'])>>>dict_countries.values() dict_values([329.5, 67.2, 38]) Проблема тут заключается в том, что мы не всегда используем их должным образом. Например, мы хотим просмотреть словарь и получить ключи. Вы можете использовать метод .keys, но знаете ли вы, что ключи можно получить, просто перебирая словарь? В этом случае использование метода .keys будет излишним. # Not using .keys() properly # Bad for key in dict_countries.keys(): print(key) # Good for key in dict_countries: print(key) Кроме того, можно придумать некоторые хитрости для получения значений словаря, например, с помощью метода .items(). # Not using .items() # Bad for key in dict_countries: print(dict_countries[key]) # Good for key, value in dict_countries.items(): print(key) print(value) 7. Никогда не использовать генераторы (или использовать их всегда) Генератор предлагает более простой синтаксис при создании новой последовательности (списка, словаря и т.д.) на основе уже определенной последовательности. Допустим, мы хотим перевести все элементы в нашем списке countries в нижний регистр. И хотя вы могли бы это сделать просто с помощью цикла for, но также вы можете упростить работу при помощи генератора списка. # Bad countries = ['USA', 'UK', 'Canada'] lower_case = [] for country in countries: lower_case.append(country.lower()) # Good (but don't overuse it!) lower_case = [country.lower() for country in countries] Генераторы – это очень полезно, но не злоупотребляйте ими! Помните правило Дзен Python: «Простое лучше, чем сложное». 8. Использование range(len()) Одни из первых функций, которые мы изучили будучи новичками – это range и len, поэтому не удивительно, почему многие люди имеют дурную привычку писать range(len()) при переборе списков. Допустим у нас есть два списка: countries и populations. Если мы хотим пройтись по обоим спискам одновременно, то, вероятнее всего, вы воспользуетесь range(len()). # Using range(len()) countries = ['USA', 'UK', 'Canada'] populations = [329.5, 67.2, 38] # Bad for i in range(len(countries)): country = countries[i] population = populations[i] print(f'{country} has a population of {population} million people') И хотя это в принципе выполняет свою работу, вы все равно можете упростить задачу, воспользовавшись enumerate (или, что еще лучше, воспользовавшись функцией zip для сопряжения элементов из обоих списков). # OK for i, country in enumerate(countries): population = populations[i] print(f'{country} has a population of {population} million people') # Much Better for country, population in zip(countries, populations): print(f'{country} has a population of {population} million people') 9. Форматирование с помощью оператора + Вероятно, одна из первых вещей, которую мы изучаем в Python, - это то, как соединять строки с помощью оператора +. Это полезный, но не самый эффективный способ соединения строк в Python. Помимо этого, это не очень красиво – чем больше строк вам нужно соединить, тем больше операторов + вы будете использовать. Вместо этого вы можете воспользоваться f-строкой. # Formatting with + operator # Bad name = input("Introduce Name: ") print("Good Morning, " + name + "!") # Good name = input("Introduce Name: ") print(f'Good Morning, {name}') Преимуществом f-строк в том, что они полезны не только для конкатенации, но и для других целей. 10. Использование изменяемых значений в качестве значений по умолчанию Если вы включите изменяемое значение (например, список) в качестве параметра функции по умолчанию, то увидите нечто неожиданное. # Bad def my_function(i, my_list=[]): my_list.append(i) return my_list>>> my_function(1) [1] >>> my_function(2) [1, 2] >>> my_function(3) [1, 2, 3] В приведенном выше коде каждый раз, когда мы вызываем функцию my_function, список my_list сохраняет значения из предыдущих вызовов (а мы, скорее всего, хотим инициировать пустой список при каждом вызове функции). Чтобы избежать такой проблемы, мы должны установить этот параметр my_list равным None и добавить условие if как показано ниже. # Good def my_function(i, my_list=None): if my_list is None: my_list = [] my_list.append(i) return my_list>>> my_function(1) [1] >>> my_function(2) [2] >>> my_function(3) [3]
img
Пришло время заняться некоторыми более продвинутыми и интересными функциями протокола маршрутизации Open Shortest Path First. Мы начинаем с изучения конфигурации и проверки различных областей OSPF. Это упражнение является не только забавным, но и действительно может закрепить знания о том, как эти области функционируют и почему они существуют. Видео: протокол OSPF (Open Shortest Path First) за 8 минут OSPF LSA Types Области (Areas) - это фундаментальная концепция OSPF. Это то, что делает протокол маршрутизации иерархическим, как мы любим говорить. Существует основная магистральная область (область 0), которая соединяется с нормальными, не магистральными областями. Магистраль может также соединяться с особыми типами областей, которые мы подробно рассмотрим в этой группе статей. Такая иерархическая природа конструкции помогает гарантировать, что протокол является очень масштабируемым. Мы можем легко уменьшить или исключить ненужные потоки трафика маршрутизации и связи между областями, если это необходимо. Магистральная и не магистральная область (Backbone и Non-Backbone Areas) Вернемся немного назад к нашим предыдущим сообщениям в статьях об OSPF. На рисунке 1 показана простая многозонная сеть. Сейчас я настрою эту сеть, используя мой любимый подход к конфигурации, команду конфигурации уровня интерфейса ip ospf. Пример 1 показывает конфигурацию всех трех устройств. Рисунок 1: Магистральная и не магистральная область (Backbone и Non-Backbone Areas) Пример 1: Настройка магистральных и не магистральных областей ATL Router: ATL#conf t Enter configuration commands, one per line. End with CNTL/Z. ATL(config)#interface fa0/0 ATL(config-if)#ip ospf 1 area 0 ATL(config-if)#interface lo0 ATL(config-if)#ip ospf 1 area 0 ATL(config-if)#end ATL# ATL2 Router: ATL2#conf t Enter configuration commands, one per line. End with CNTL/Z. ATL2 (config)#interface fa0/0 ATL2 (config-if)#ip ospf 1 area 0 ATL2 (config-if)#interface *Mar 27 22 :03 :27.815 : %0SPF-5-ADJCHG : Process 1, Nbr 1 .1.1 .1 on FastEthernet0/0 from LOADING to FULL, Loading Done ATL2 (config-if)#interface fa1/0 ATL2 (config-if)#ip ospf 1 area 1 ATL2 (config-if)#end ATL2# ORL Router: ORL# conf t Enter configuration commands, one per line. End with CNTL/Z. ORL( config )#interface fa1/0 ORL(config-if)#ip ospf 1 area 1 ORL(config-if)#end ORL# *Mar 27 22 :04:21.515: %0SPF-5-ADJCHG: Process 1, Nbr 10.23.23.2 on FastEthernet1/0 from LOADING to FULL , Loading Done Обратите внимание на простоту этой конфигурации, даже если мы настраиваем довольно сложный протокол маршрутизации. Area Border Router (ABR) находится в ATL2 с одним интерфейсом в магистральной и одним в не магистральной области. Обратите также внимание, как мы получаем некоторые «бонусные» проверки. Когда мы настраиваем интерфейсы, мы можем видеть, что OSPF-соседства формируются между устройствами. Это избавляет нас от необходимости проверять их «вручную» с помощью следующей команды: ATL2# show ip ospf neighbor Интересной проверкой для нас здесь является проверка префикса 1.1.1.0/24 с устройства ATL (а также удаленной связи между ATL и ATL2). Мы проверяем это на ORL, чтобы проверить многозональную конфигурацию OSPF. Поскольку это «нормальная» область, все LSA должны быть разрешены в этой области, и мы должны видеть, что префикс появляется как межзонный маршрут OSPF. show ip route ospf Хотя это не часто требуется при устранении неполадок, но мы можем изучить базу данных OSPF, чтобы увидеть различные типы LSA. show ip ospf database Записи состояния соединения маршрутизатора являются Type 1 LSA. Это конечные точки в нашей локальной области 1. Записи состояния net link-это Type 2 LSA. Здесь мы видим идентификатор маршрутизатора назначенного маршрутизатора (DR). Наконец, суммарные состояния сетевых ссылок — это Type 3 LSA. Это префиксы, которые ABR посылает в нашу область. Конечно же, это loopback (1.1.1.0) и удаленная сеть (10.12.12.0). Примечание: интерфейс обратной связи (loopback interface) объявлен как хост-маршрут 32-разрядной версии. Чтобы изменить это, вы можете просто использовать команду ip ospf network point-to-point на интерфейсе loopback. Это изменяет тип сети от типа loopback для OSPF и вызывает объявление маски в том виде, в каком она настроена. Теперь пришло время добавить к этой истории еще и другое. Давайте настроим некоторые внешние префиксы и введем их в домен OSPF. Это просто благодаря loopback interfaces. Мы создадим некоторые из них на маршрутизаторе ATL, запустим EIGRP на них, а затем перераспределим их в OSPF. ATL#conf t Enter configuration commands, one per line. End with CNTL/Z . ATL (config)#interface lo10 ATL (config-if)#ip address 192.168.10.1 255.255.255.0 ATL (config-if)#interface loopback 20 ATL (config-if)#ip address 192.168.20.1 255.255.255.0 ATL (config if)#router eigrp 100 ATL (config-router)#network 192 .168.10.1 0.0.0.0 ATL (config-router)#network 192.168.20.1 0.0.0.0 ATL (config-router)#router ospf 1 ATL (config-router)#redistribute eigrp 100 subnets metric 1000 ATL (config-router)#end ATL# Теперь у нас есть еще более интересные проверки на устройстве ORL. Во-первых, таблица маршрутизации: show ip route ospf Обратите внимание, что удаленные префиксы перечислены как маршруты E2. Это значение по умолчанию для внешних маршрутов OSPF типа 2. Это означает, что метрика остается неизменной, поскольку префикс течет от ASBR (автономного системного пограничного маршрутизатора) к внутреннему спикеру OSPF. Вы можете изменить тип на Type 1, если хотите, когда вы выполняете перераспределение. Возможно, больший интерес представляет база данных OSPF: show ip ospf database Обратите внимание, как мы подбираем Type 4 LSA (summary ASB link state), который является идентификатором маршрутизатора (1.1.1.1) ASBR (ATL). Мы также получаем Type 5 LSA, которые являются внешними префиксами. На этом мы завершим ПЕРВУЮ часть нашей продвинутой серии блогов OSPF. В следующий раз мы рассмотрим создание stubby areas, totally stubby areas, not so stubby areas (NSSA), и totally NSSA.
img
Сегодня поговорим о процессе настройки модуля Callback в FreePBX 13. Как настроить и использовать данный модуль и читайте ниже. Что это? Коллбэк (callback) - функционал обратного звонка, который меняет направление вызова на "обратное" - исходящий звонок от абонента путём сброса вызова становится входящим для абонента, то есть IP - АТС набирает номер позвонившего. Вы спросите, зачем это надо? Данный функционал обычно используется для уменьшения счетов у мобильных операторов и/или счетов при международных звонках. Как правило, вызов данной функции совершается из IVR-меню или настраивается входящий маршрут на CallBack. Настройка CallBack в FreePBX Первый шаг крайне прост – в веб-интерфейсе необходимо открыть следующую вкладку: Applications – Callback. Перейдя в меню настройки модуля, нажмите на кнопку + Add Callback Переходим к настройке доступных опций Сallback Description – описание вашего коллбэка, полезно если несколько коллбэков используются на вашей АТС Callback Number – опциональное поле, если оставить пустым, то АТС совершит вызов по номеру, с которого до этого пришёл вызов. В ином случае, АТС совершит вызов по номеру, указанному в данном поле Delay Before Callback – опциональное поле, интервал (в секундах) между активацией модуля и совершением вызова с АТС. По умолчанию интервал равен нулю Destination after Callback – маршрутизация вызова после звонка: к примеру можно направить вызов на требуемый номер/ринг-группу/IVR-меню и так далее Созданные коллбэки можно редактировать и удалять, если, к примеру, при его создании вы в чём-то ошиблись.
ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59