По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
Всем привет! В сегодняшней статье расскажем об одном из самых полезных, на наш взгляд, коммерческих модулей FreePBX и продемонстрируем процесс его настройки. Особенно поможет данный модуль системным администраторам, которым часто приходится подготавливать телефонные аппараты для новых сотрудников, а также обслуживать и обновлять их. Итак, встречайте - модуль EndPoint Manager! Его стоимость на момент написания статьи 17.01.18 составляет 149$ (8 418 рубля), лицензия предоставляется на 25 лет. Согласитесь, в масштабах компании - это не такая большая сумма, а время Вашего админа – бесценно :) /p> Конечно, если Вы являетесь счастливым обладателем телефонов от Sangoma, то благами модуля EPM вы можете пользоваться бесплатно :) Обзор Модуль EndPoint Manager позволяет организовать функционал auto-provisioning, когда телефонный аппарат нужно только подключить к сети, а все необходимые настройки он автоматически скачает с сервера, после чего сразу же будет готов к работе. Помимо телефонных аппаратов, с помощью данного модуля можно также настраивать шлюзы, конференц-фоны, беспроводные трубки, дверные телефоны и пэйджинг устройства самых популярных производителей VoIP оборудования: Aastra Algo AND Audiocodes Cisco Cortelco Cyberdata Digium Grandstream HTek Mitel Mocet Obihai Panasonic Phoenix Audio Polycom Sangoma Snom Uniden Vtech Xorcom Yealink Полный список конкретных поддерживаемых устройств можно найти на сайте разработчика: https://wiki.freepbx.org/display/FPG/EPM-Supported+Device Основное предназначение EPM - это создание шаблонов (template) с необходимыми настройками, которые потом можно применять на одном или группе аналогичных устройств, что сводит подготовку устройств к минимуму. Общий механизм работы примерно такой - После создания шаблона с настройками для определённой модели телефонного аппарата, администратор, с помощью модуля EPM, привязывает данный шаблон к конкретному внутреннему номеру (extension) по MAC адресу данного устройства. После этого автоматически создаётся конфигурационный файл вида ХХХХ.cfg, где ХХХХ – MAC адрес устройства, который, сервер FreePBX с установленным EPM, хранит на файловом хранилище. Когда телефонный аппарат подключается в сеть, то вместе с IP адресом, он получает по DHCP адреса сервера (option 66), на котором для него создан файл конфигурации. После чего телефон обращается на данный сервер и скачивает готовую конфигурацию и, опционально, актуальную прошивку. То есть, по сути, для того чтобы ввести новый телефон в эксплуатацию, нам нужно только подключить его в сеть, узнать его MAC адрес и всё! Более подробно про процесс auto-provisioning и option 66 можно почитать в нашей статье Модуль имеет несколько подразделов, каждый из которых имеет своё предназначение, рассмотрим их: Global Settings - в данном разделе настраиваются общие параметры модуля, такие как внутренняя и внешняя адресация, порты, административные и пользовательские пароли для устройств Extension Mapping - данный раздел предназначен для настройки соответствия внутреннего номера, настроенного на IP-АТС и назначения определённого шаблона конфигурации. Привязка происходит по MAC адресу аппарата Brands - данный раздел содержит шаблоны конфигураций для определённого бренда и моделей VoIP оборудования. Брендов может быть несколько, они добавляются в разделе Add Brand. По умолчанию тут только шаблон для телефонов Sangoma. Add Brand - здесь Вы можете добавить новый бренд, для которого в дальнейшем будете создавать шаблоны конфигураций Image Management - данный раздел предназначен для управления фоновым изображением на телефонном аппарате, если конечно он его поддерживает Ringtone Management - данный раздел предназначен для управления рингтонами звонка на телефонном аппарате; Basefile Edit - с помощью данного раздела можно изменять дефолтные параметры самих шаблонов для любой модели телефона. Как правило, это подразумевает редактирование XML файла конфигурации. Custom Extensions - данный раздел предназначен для настройки телефонных аппаратов, которые не зарегистрированы на вашей АТС. Поскольку модуль EPM по умолчанию видит только пул внутренних номеров локальной АТС, то для настройки удалённых устройств, например с другой АТС, необходимо сначала объявить их в этом разделе. Firmware Management - данный раздел позволяет управлять прошивками устройств всех брендов. Помимо этого, можно управлять их версиями и назначать определённому шаблону ту или иную версию прошивки. Network Scan - с помощью данной утилиты можно просканировать сеть и получить список MAC адресов устройств, которым ещё не назначены шаблоны конфигураций и сразу же их назначить через раздел Extension Mapping. Стоит отметить, что поскольку MAC адреса не маршрутизируются, то определить можно только устройства, находящиеся в одной сети с IP-АТС, поэтому здесь нужно указывать локальную сеть. То есть, например, если IP адрес Вашей АТС – 192.168.11.64/24, то Вы сможете успешно просканировать только устройства в сети 192.168.11.0/24. Настройка Рассмотрим подробнее каждый из разделов, описанных выше. После установки, модуль появляется в разделе Settings. Доступ к разделам модуля осуществляется по нажатию на кнопку в правом углу: Первое, с чего необходимо начать - это глобальные настройки Global Settings. Internal IP - здесь указываем локальный адрес нашей IP- АТС. Можно ввести слово auto, тогда локальный IP адрес будет определён автоматически. External IP - в этом поле указываем внешний адрес нашей IP-АТС или валидный FQDN. Это поле нужно только если у вас есть телефоны, которые подключаются из вне. Можно ввести слово auto, тогда внешний IP адрес будет определён автоматически, чтобы не использовать данное поле – введите none Ports - данная секция отображает номера портов, которые настроены для различных сервисов - Web Server - порт для доступа к вэб-интерфейсу модуля, HTTP Provisioning - порт для auto-provisioning по протоколу HTTP, TFTP Provisioning - порт для auto-provisioning по протоколу TFTP, RESTful Apps - порт использующийся для интеграции Phone Apps с IP-АТС. Номера данных портов настраиваются в модуле System Admin, настроить через EPM их нельзя. Phone Admin Password - здесь можно административный пароль для доступа к вэб-интерфейсу телефонных аппаратов. Пароль будет одинаковым для всех устройств под управлением модуля EPM Phone User Password - некоторые телефоны имеют разные уровни доступа к вэб-интерфейсу управления. В данном поле можно настроить пароль для пользовательского уровня. ReSync Time - время, по истечению которого телефон будет заного запрашивать конфигурацию с сервера, чтобы актуализировать её. По умолчанию это день – 86400 секунд XML-API (RestAPI) Default Login - разрешает доступ к Phone Apps, если это поддерживается телефоном. Extension Mapping IP Address и Phone Status - здесь настраивается как будет отображаться статус телефонного аппарата в разделе Extension Mapping. Можно показывать IP адрес телефона и время последнего ping’а данного аппарата По завершению настроек необходимо нажать Save Global Теперь, когда у нас есть глобальные настройки, можно добавлять и настраивать шаблоны для любых брендов телефонных аппаратов, которые будут подключаться к нашей IP-АТС. Для этого открываем меню и кликаем Add Brand, перед нами откроется список поддерживаемых производителей, выберем Cisco. После этого, перед нами откроется окно с параметрами настроек нового шаблона для устройств Cisco: Внимание! Дальнейшие параметры могут отличаться в зависимости от выбранного в предыдущем шаге производителя. Ниже будет приведён пример для Cisco Template Name - имя шаблона. Рекомендуем указывать здесь модели, для которых создаётся шаблон, а также для каких телефонных аппаратов он предназначен – локальных или удаленных. Например, в нашем случае шаблон будет для локальных телефонов Cisco SPA 504G Destination Address - адрес IP-АТС, на который телефон будет обращаться для того, чтобы зарегистрироваться. Значения Internal и External берутся из Global Settings или же вы можете указать адрес вручную нажав Custom Provision Server Protocol - протокол, который будут использовать телефоны для получения своих конфигурационных файлов - TFTP или HTTP Provision Server Address адрес provisioning сервера, на который телефон будет обращаться для получения конфигурации. Значения Internal и External берутся из Global Settings или же вы можете указать адрес вручную нажав Custom. В нашем случае - Destination Address и Provision Address будут совпадать и являться адресом IP-АТС 192.168.11.64, это наиболее распространённый случай. Time Zone - временная зона Primary Time Server и Time Server 2 - сервера синхронизации времени NTP Daylight Savings - включает переход на летнее время Background Image - фоновое изображение для телефонного аппарата. Загружается в разделе Image Management Line Label - позволяет вывести идентификатор линии на LCD экран телефона (если он есть): Extension - выводит внутренний номер, например “7007” Name - выводит имя внутреннего номера, например “Alex Dobronravov” Name-Extension - выводит имя и номер, например “Alex Dobronravov 7007” Обратите внимание, что в зависимости от используемого телефона количество отображаемых символов может быть ограничено Dial Pattern - здесь можно поменять стандартные шаблоны набора номера, используемые телефоном. Символы в данном поле будут зависеть от выбранного производителя Firmware Version - здесь мы можем настроить загрузку прошивок для моделей телефонных аппаратов, для которых создаётся шаблон. При нажатии на кнопку Firmware Management мы попадаем в соответствующий раздел, в котором уже доступны все прошивки для телефонов Cisco (в том числе и для нужного нам SPA 504G), выберем самый актуальный пак. В каждом паке содержатся прошивки для разных моделей телефонов. Из пака загружаются только прошивки для моделей, которые выбраны в шаблоне. Можно указать разные версии прошивок, для этого нужно выбрать разные паки в Firmware Slot 1 и с После чего в настройках шаблона в поле Firmware Version мы можем выбрать нужный слот, чтобы загрузить его на все телефонные аппараты, которые будут выбраны в данном шаблоне. Available Phones - в данном списке находим нужную нам модель телефонного аппарата (в нашем случае – SPA 504G) и кликаем на неё. После чего перед нами открывается окно с настройками кнопок телефонного аппарата. Доступные настройки будут зависеть от выбранной модели В данном случае мы настроили на первой кнопке телефона SPA 504G отображение линии, а на второй BLF по номеру 3032. Отметим, что подобная конфигурация будет присвоена всем телефонам, которым мы назначим данный шаблон. Если их много, то некоторым, например, может не понадобиться BLF одного и того же номера, учитывайте это. В дальнейшем, настройки кнопок можно будет изменить для каждого телефона индивидуально. Отметим также, что можно создать один шаблон для нескольких моделей телефонов (а также для панелей расширения Expansion Module и других устройств, например, в случае Cisco - FXS), для этого просто отметьте и настройте необходимые модели: По завершению настройки шаблона доступно несколько опций сохранения - Save - просто сохранит новый шаблон, Save and Rebuild Config(s) - сохранит конфигурацию подготовит её к загрузке на телефоны, которые используют данный конфиг при следующем цикле синхронизации, Save, Rebuild and Update Phones - данный вариант перезапишет новую конфигурацию, подготовит её к загрузке на телефоны, которым назначен данный шаблон и отправят её на эти телефоны, что может вызвать перезагрузку телефонов. Стоит отметить, что пока никаким телефонам не назначен данный шаблон – при использовании опций Save and Rebuild Config(s) и Save, Rebuild and Update Phones ничего не произойдёт, опции действуют только когда в разделе Extension Mapping есть активные устройства. Для более тонкой настройки параметров, которые невозможно настроить стандартными средствами шаблона, используйте функционал Basefile Edit. Он предназначен для опытных пользователей и позволяет править конфигурацию шаблона для определённой модели на уровне её конфигурационного файла, как правило – формата XML Завершение настройки и назначение настроенного шаблона телефонным аппаратам Теперь, когда мы закончили с настройкой шаблона, самое время привязать его к внутреннему номеру и к конкретному телефонному аппарату. Для этого есть 2 способа: Предварительно убедитесь, что настраиваемые телефонные аппараты подключены в сеть и получают адреса по DHCP. Также, на DHCP сервере должна быть настроена опция 66 (option 66), сообщающая телефону адрес provisioning сервера, на котором хранится конфигурация. Заходим в раздел Extension Mapping и нажимаем Add Extension. Выбираем внутренний номер, из списка зарегистрированных на нашей IP-АТС, которому хотим назначить шаблон (тут также можно настроить Custom Extension, о котором говорилось выше), далее выбираем учётную запись SIP, в нашем случае - Account 1. Во втором столбце выбираем бренд - Cisco и ниже прописываем MAC адрес настраиваемого телефона. В последнем столбце выбираем шаблон, который мы только что настроили (в нашем случае spa504g_internal) и модель телефона (в нашем случае Cisco SPA 504G) После этого выбираем способ сохранения конфигурации и нажимаем Use Selected. Мы выбрали Save, Rebuild and Update Phones, чтобы конфиг сразу же отправился на телефон. Заходим в модуль Extensions ищем нужный внутренний номер и открываем вкладку Other. В разделе Endpoint заполняем необходимые поля и нажимаем Submit В обоих случаях, после данных манипуляций, создаётся конфигурационный файл XXXXYYYYZZZZ.cfg , где XXXXYYYYZZZZ – МАС адрес телефонного аппарата и хранится в файловом хранилище сервера. Когда телефон подключится в сеть, то от DHCP сервера он получит IP адрес, а также через опцию 66 – адрес provisioning сервера, в нашем случае – это TFTP сервер 192.168.11.64. Телефонный аппарат обратится на TFTP сервер и скачает от туда свой конфигурационный файл XXXXYYYYZZZZ.cfg. Таким образом, телефон будет сразу готов к работе.
img
Cron - это демон планирования, который выполняет задачи с заданными интервалами. Эти задачи называются заданиями cron и в основном используются для автоматизации обслуживания или администрирования системы. Например, вы можете установить задание cron для автоматизации повторяющихся задач, таких как резервное копирование баз данных или данных, обновление системы последними обновлениями безопасности, проверка использования дискового пространства, отправка электронных писем, перезагрузка сервера и так далее. В некоторых приложениях, таких как Drupal или Magento, для выполнения определенных задач требуются задания cron. Задания cron могут быть запланированы по минуте, часу, дню месяца, месяцу, дню недели или любой их комбинации. Про Linux за 5 минут
img
Типы данных в Python Кортежи в Python – это один из четырех встроенных типов данных, которые используются для того, чтобы хранить наборы данных. К остальным типам данных относятся списки, множества и словари. У каждого из типов данных есть свои уникальные особенности, и каждый из них используется по-своему.  Иллюстрация списка, кортежа и множества Списки – это  изменяемые упорядоченные последовательности элементов. Как правило, они используются для того, чтобы хранить однотипные данные. Тем не менее, их также можно использовать для хранения элементов, которые имеют разные типы данных.  my_list = [1, 2, 3, 4, 5] print(my_list) Списки в Python Множества – это  изменяемые неупорядоченные наборы уникальных элементов. Этот тип данных полезен для выполнения математических операций с данными. my_set = {"apple", "banana", "cherry", "apple"} print(my_set) Множества в Python Если вы выполните код, приведенный выше, второе вхождение слова  "apple" в множестве будет проигнорировано, так как множества хранят только уникальные элементы. Словари – это  изменяемые неупорядоченные наборы пар ключ-значение. Они используются для того, чтобы можно было связать ключ со значением (все как в реальном словаре).  my_dict = {"Alice": 25, "Bob": 30, "Charlie": 35} print(my_dict) Словари в Python Кортежи – это  неизменяемые упорядоченные последовательности элементов. Они полезны для хранения и передачи связанных фрагментов данных, которые не подлежат изменениям после того, как они были созданы.  my_tuple = ("apple", "banana", "cherry") print(my_tuple) Кортежи в Python Если вы создаете кортеж с несколькими элементами, то скобки можно не использовать, хотя их довольно часто используют для того, чтобы внести ясность.  my_tuple = 1, 2, 3 print(my_tuple) При создании кортежи могут быть записаны как с помощью круглых скобок, так и без них Что такое кортеж? Как мы уже говорили выше, кортеж – это упорядоченная и неизменяемая последовательность элементов. Это значит, что после того, как кортеж будет создан, элементы в нем менять будет нельзя. Ниже приведен код для создания кортежа: my_tuple = (1, 2, 3, 'four', 5.0) В нашем случае  my_tuple - это кортеж, который содержит пять элементов. Обратите внимание, что элементы в кортеже могут быть разных типов. Например, в примере выше кортеж содержит три значения типа integer, одно – типа string, и одно – типа float (или double).  Получить доступ к элементам кортежа довольно просто. Для того, чтобы это сделать, вам нужно их просто проиндексировать, как в обычном списке. print(my_tuple[0])  # outputs 1 print(my_tuple[3])  # outputs 'four' Обращение к элементу в кортеже Можно обратиться сразу к нескольким элементам кортежа. Сделать это можно с помощью срезов. print(my_tuple[1:3])  # outputs (2, 3) Срезы кортежа Возьмите код, который приведен выше, и попробуйте получить доступ к элементу, чей индекс выходит за пределы диапазона кортежа. Например, попробуйте обратиться к элементу с индексом 6. Получите ли вы ошибку? Попробуйте выяснить!  Одно из основных преимуществ использования кортежей (по сравнению со списками) заключается в том, что их можно быстрее перебирать, и они более эффективно используют память. Именно поэтому они считаются отличным вариантом для хранения какого-то фиксированного набора значений, который не нужно менять. Но, поскольку кортежи неизменяемы, то после его создания вы не сможете изменять элементы. В связи с этим, если ваша задача подразумевает изменение набора элементов, то вместо кортежей вам придется использовать списки.  Основные функции Ниже перечислены некоторые примеры использования функций и методов для кортежей в Python: len(tuple) : возвращает длину кортежа. my_tuple = (1, 2, 3, 'four', 5.0) print(len(my_tuple))  # outputs 5 Получение длины кортежа tuple(seq) : преобразует последовательность (например, список или строку) в кортеж. my_list = [1, 2, 3] my_tuple = tuple(my_list) print(my_tuple)  # outputs (1, 2, 3) my_string = 'hello' my_tuple = tuple(my_string) print(my_tuple)  # outputs ('h', 'e', 'l', 'l', 'o') Преобразование последовательности в кортеж tuple.count(value) : возвращает количество вхождений указанного значения в кортеж. my_tuple = (1, 2, 3, 2, 2, 'hello') print(my_tuple.count(2))  # outputs 3 print(my_tuple.count('goodbye'))  # outputs 0 Подсчет количества вхождений указанного значения Так как в кортеже  my_tuple нет слова  goodbye , то вывод для конкретно этого оператора равен  0 ( строка 3 ). tuple.index(value) : возвращает индекс первого вхождения указанного значения в кортеж. my_tuple = (1, 2, 3, 2, 2, 'hello') print(my_tuple.index(2))  # outputs 1 print(my_tuple.index('hello'))  # outputs 5 #print(my_tuple.index(4)) # will throw an error Получение индекса указанного значения Обратите внимание, что если вы будете выполнять поиск для значения, которого нет в кортеже  my_tuple , то вы получите сообщение об ошибке  "x not in tuple" . Если вы раскомментируете последнюю строку кода, то сможете это увидеть.  Функции  max(tuple) и  min(tuple) возвращают максимальное и минимальное значения в кортеже соответственно. Если кортеж состоит только из строк, то функция  min(tuple) вернет строку, которая будет первой в алфавитном порядке, а функция  max(tuple) - ту, которая будет последней. И последнее, если кортеж состоит как из чисел, так и из строк, то обе функции выдадут ошибку. my_tuple = (1, 2, 3, 4, 5) print(max(my_tuple))  # outputs 5 print(min(my_tuple))  # outputs 1 alphabetical_tuple = ("apple", "banana", "giraffe", "fox", "eel") print(max(alphabetical_tuple))  # outputs giraffe print(min(alphabetical_tuple))  # outputs apple alphanumeric_tuple = (1, "apple", 2, "dog") #print(max(alphanumeric_tuple))  # error #print(min(alphanumeric_tuple))  # error Получение максимального и минимального значения в кортеже sorted(tuple) : возвращает новый отсортированный список из элементов кортежа. my_tuple = (3, 1, 4, 1, 5, 9, 2) sorted_tuple = sorted(my_tuple) print(sorted_tuple)  # outputs [1, 1, 2, 3, 4, 5, 9] Сортировка элементов в кортеже any(tuple) : если хотя бы один элемент в кортеже истинен, возвращает  True , в противном случае -  False .  Примечание : многие значения в Python могут расцениваться как  True или  False . True и  False – это логические литералы, которые определяют истину и ложь соответственно.  Целые числа 0 и 1 расцениваются как  False и  True соответственно.  Пустая срока  "" расценивается как  False , а любая непустая строка – как  True . Пустой кортеж  () или список  [] расценивается как  False , а любой непустой кортеж или список – как  True . None расценивается как  False . Получается, что для такого кортежа, как  (0, False, "", None) , функция  any() вернет  False , так как все элементы кортежа расцениваются как  False . Однако для такого кортежа, как  (1, True, "hello") , функция  any() вернет  True , так как хотя бы один элемент кортежа имеет значение  True . my_tuple1 = (False, 0, None, '', ()) my_tuple2 = (False, 0, None, '', (), True) print(any(my_tuple1))  # outputs False print(any(my_tuple2))  # outputs True Применение функции  any() all(tuple) : если все элементы кортежа истины, возвращает  True , в противном случае -  False . Обратите внимание, что пустая строка считается ложным значением ( False ). my_tuple1 = (True, 1, 'hello', [1, 2, 3]) my_tuple2 = (True, 1, '', [1, 2, 3]) print(all(my_tuple1))  # outputs True print(all(my_tuple2))  # outputs False Применение функции  all() Сложение кортежей применяется для объединения двух и более кортежей в один. tuple1 = (1, 2, 3) tuple2 = (4, 5, 6) tuple3 = tuple1 + tuple2 print(tuple3) #outputs (1, 2, 3, 4, 5, 6) Сложение двух кортежей Умножение кортежа на число применяется для создания нового кортежа, который будет состоять из элементов уже существующего кортежа, повторенных определенное количество раз.  my_tuple = ("apple", "banana") new_tuple = my_tuple * 3 print(new_tuple) # outputs ('apple', 'banana', 'apple', 'banana', 'apple', 'banana') Умножение кортежа на целое число В примере выше мы определили кортеж my_tuple , который содержит два строковых значения. После чего мы используем оператор * для того, чтобы создать новый кортеж  new_tuple путем трехкратного повторения элементов кортежа  my_tuple .  Обратите внимание, что  tuple1 + tuple2 и  tuple1 * n в приведенных выше примерах – это обычные выражения, которые объединяют или делают срезы кортежей и не требуют использования каких-то дополнительных функций или методов.  Упаковка и распаковка кортежей Упаковка подразумевает объединение последовательности значений в один кортеж. Для того, чтобы это сделать, необходимо записать значения через запятую в круглых скобках. my_tuple = (1, 2, 'three') Упаковка кортежа В данном случае значения  1 ,  2 и  'three' были объединены в кортеж, который, в свою очередь, был присвоен переменной  my_tuple .  Что же касается  распаковки , то она подразумевает извлечение значений из кортежа и присваивание их отдельным переменным. Это можно выполнить, указав в левой части оператора присваивания несколько имен переменных через запятую и присвоив им кортеж. В предыдущем примере мы присваивали некоторые значения переменной  my_tuple . В данном примере кортеж  my_tuple распаковывается, и эти значения присваиваются переменным  a ,  b и  c соответственно. a, b, c = my_tuple print(a)  #outputs 1 print(b)  #outputs 2 print(c)  #outputs 'three' Распаковка кортежа Что произойдет, если мы в приведенном выше коде для распаковки значений кортежа  my_tuple будем использовать только переменные  a и  b ? Напомню, что кортеж  my_tuple содержит три элемента. Если вы так сделаете, то получите сообщение об ошибке  ValueError: too many values to unpack (expected 2) . Вы можете попробовать это сами, подкорректировав приведенный выше код. Также можете посмотреть, что будет, если вы будете использовать четыре переменные -  a ,  b ,  c и  d . Упаковка и распаковка Вложенные кортежи Вложенные кортежи – это кортежи, которые в качестве элементов содержат другие кортежи.  Для того, чтобы создать вложенный кортеж, нужно просто добавить один или несколько кортежей через запятую в другой кортеж: my_tuple = ((1, 2), (3, 4), (5, 6)) Вложенный кортеж my_tuple в примере выше – это вложенный кортеж, который в качестве элементов содержит три кортежа, каждый из которых, в свою очередь, содержит по два целых числа.  Для того, чтобы обратиться к элементам вложенного кортежа, используется либо обычное индексирование, либо вложенное.  print(my_tuple[0]) # outputs (1, 2) print(my_tuple[1][0])  # outputs 3 print(my_tuple[2][1])  # outputs 6 Обращение к элементам во вложенном кортеже Первый оператор  print   печатает первый элемент кортежа  my_tuple , то есть кортеж  (1, 2) . Во втором операторе используется вложенная индексация, с помощью которой мы обращаемся к первому элементу второго кортежа, то есть  3 . В третьем операторе также используется вложенная индексация, но здесь мы обращаемся ко второму элементу третьего кортежа, то есть  6 . Кортежи как ключи в словаре Помимо всего прочего, кортежи можно использовать в качестве ключей в словаре. Так как кортежи не могут быть изменены после того, как будут созданы, их можно смело использовать в качестве надежного и неизменяемого ключа в словаре.  Ниже приведен пример создания словаря с кортежами в качестве ключей: my_dict = {('apple', 1): 'red', ('banana', 2): 'yellow', ('orange', 3): 'orange'} Ключ в данном случае – это кортеж, который содержит некоторый фрукт и число. А значения – это строки, которые определяют цвета фруктов. Обратиться к значениям словаря можно с помощью кортежей, которые выступают в роли ключей: print(my_dict[('apple', 1)])  # outputs 'red' print(my_dict[('banana', 2)])  # outputs 'yellow' print(my_dict[('orange', 3)])  # outputs 'orange' Использование кортежей в качестве ключей в словаре Преимущества кортежей Кортежи имеют ряд преимуществ в сравнении с другими типами данных, например, Неизменяемость . Кортежи неизменяемы, то есть вы не можете изменить их содержимое после того, как создадите. За счет этой особенности кортежи считаются более безопасным типом данных, который не подвержен частым ошибкам в отличие от изменяемых типов данных, таких как списки. Последние могут быть непреднамеренно изменены в других частях программы. Кортежи неизменяемы Упорядоченность . Кортежи – это упорядоченные наборы элементов, которые могут оказаться очень полезными, если вам нужно хранить связанные фрагменты данных, обращаться к которым нужно в определенном порядке.  Лучшая производительность . Кортежи работают куда быстрее, чем списки, так как требуют меньшего объема памяти и могут быть оптимизированы интерпретатором Python. Подходят в качестве ключей . Кортежи можно использовать в качестве ключей в словарях, а вот списки – нельзя. А значит, если вы хотите создать словарь, который бы сопоставлял связанные фрагменты данных друг с другом, то в качестве ключей словаря вы можете использовать кортежи.  Результаты работы функции . Зачастую кортежи используют для того, чтобы функция могла возвращать несколько значений, так как они могут содержать любое количество элементов и легко подлежат распаковке. Ниже приведен пример, в котором функция возвращает несколько значений, упакованных в кортеж  return_tuple . def calculate_statistics(numbers):    n = len(numbers)    total = sum(numbers)    mean = total / n    variance = sum((x - mean) ** 2 for x in numbers) / n    stdev = variance ** 0.5    return_tuple = (total, mean, stdev)    return return_tuple my_numbers = [1, 2, 3, 4, 5] total, mean, stdev = calculate_statistics(my_numbers) print("Total:", total) print("Mean:", mean) print("Standard deviation:", stdev) Недостатки кортежей Несмотря на то, что у кортежей есть несколько преимуществ (по сравнению с другими типами данных в Python), у них также есть и недостатки. Вот некоторые из них: Неизменяемость . Неизменяемость может быть как преимуществом, так и недостатком.  Так как кортежи неизменяемы, то для того, чтобы внести в него некоторые изменения, приходится создавать новый кортеж. И если вы будете создавать много кортежей, это может оказаться довольно затратным по времени и привести к увеличению количества используемой памяти.  Ограниченная функциональность . Если сравнивать кортежи с другими типами данных, например, списками, то они имеют ограниченную функциональность. Например, у кортежей нет таких методов, как  append() ,  insert() или  remove() , которые есть у списков.  Не подходят для больших наборов данных . Кортежи не подходят для больших наборов данных, так как они хранятся в памяти и, если они будут содержать слишком большое количество элементов, то будут занимать много места. В ситуациях с большими наборами данных, больше подойдут такие типы данных, как массивы или генераторы.  Не подходят для больших наборов данных Неудобны для чтения . В некоторых ситуациях кортежи читать труднее, чем другие типы данных, например, списки (особенно если в кортеже содержится много элементов). Это объясняется тем, что кортежи, как правило, записываются в круглых скобках и через запятые, что может зрительно сбивать с толку некоторых программистов.  Заключение и основные моменты Кортежи – это основной тип данных Python, с помощью которого можно хранить наборы значений и управлять ими. В этой статье мы рассмотрели основные принципы создания обычных и вложенных кортежей, обращения к ним, упаковки и распаковки кортежей, а также использования кортежей в качестве ключей в словарях. Вот некоторые ключевые моменты, о которых не стоит забывать: Кортежи неизменяемы. Доступ к отдельным элементам кортежа можно получить с помощью индексов (как и в случае со списками). Кортежи можно использовать в качестве ключей в словарях, что делает их отличным инструментом для управления данными. Упаковка кортежей позволяет объединять несколько значений в один кортеж. Распаковка кортежей позволяет присваивать элементы кортежа нескольким переменным за раз. Вложенные кортежи могу использоваться для представления более сложных структур данных. 
ЗИМНИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59