Сообщество - Программирование на python

Программирование на python

716 постов 11 876 подписчиков

Популярные теги в сообществе:

101 игра на python. Шпаргалки. Структуры данныx python


1. Списки (Lists)

  • Определение: Списки в Python – это упорядоченные, изменяемые коллекции элементов. Это значит, что ты можешь добавлять, удалять и изменять элементы в списке, и порядок элементов имеет значение.

  • Представление: Списки создаются с помощью квадратных скобок [], а элементы разделяются запятыми.

101 игра на python. Шпаргалки. Структуры данныx python Гайд, Программирование, Python, Информатика, Структуры данных, Шпаргалка, Длиннопост
  • Особенности:

    • Могут содержать элементы разных типов данных (числа, строки, булевы значения, другие списки и т.д.).

    • Поддерживают индексацию (доступ к элементу по его позиции, начиная с 0).

    • Изменяемые (mutable).

  • Примеры:

101 игра на python. Шпаргалки. Структуры данныx python Гайд, Программирование, Python, Информатика, Структуры данных, Шпаргалка, Длиннопост
101 игра на python. Шпаргалки. Структуры данныx python Гайд, Программирование, Python, Информатика, Структуры данных, Шпаргалка, Длиннопост

2. Словари (Dictionaries)

  • Определение: Словари в Python – это неупорядоченные коллекции элементов, где каждый элемент состоит из пары "ключ-значение".

  • Представление: Словари создаются с помощью фигурных скобок {}, а пары "ключ-значение" разделяются двоеточием :.

    my_dict = {"name": "John", "age": 30, "city": "New York"}

  • Особенности:

    • Ключи должны быть уникальными и неизменяемыми (обычно строки или числа), а значения могут быть любого типа.

    • Доступ к значениям осуществляется по ключу.

    • Изменяемые (mutable).

    • Неупорядоченные (порядок может не сохранятся)

  • Примеры:

101 игра на python. Шпаргалки. Структуры данныx python Гайд, Программирование, Python, Информатика, Структуры данных, Шпаргалка, Длиннопост

3. Кортежи (Tuples)

  • Определение: Кортежи в Python – это упорядоченные, неизменяемые коллекции элементов.

  • Представление: Кортежи создаются с помощью круглых скобок (), а элементы разделяются запятыми.

    my_tuple = (1, 2, 3, "apple", "banana", True)

  • Особенности:

    • Аналогичны спискам, но являются неизменяемыми (immutable), то есть нельзя изменить элементы после создания кортежа.

    • Могут содержать элементы разных типов данных.

    • Поддерживают индексацию.

    • Используются для представления неизменяемых последовательностей.

  • Примеры:

    # Создание кортежа my_tuple = (1, 2, 3, "apple", "banana") print(f"Создание кортежа: {my_tuple}") # Доступ по индексу print(f"Элемент по индексу 2: {my_tuple[2]}") # Нельзя изменить элемент # my_tuple[0] = 0 # Это вызовет ошибку: TypeError: 'tuple' object does not support item assignment # Нельзя добавить элемент # my_tuple.append(4) # Это вызовет ошибку: AttributeError: 'tuple' object has no attribute 'append' # Нельзя удалить элемент # del my_tuple[0] # Это вызовет ошибку: TypeError: 'tuple' object doesn't support item deletion

4. SimpleNamespace

  • Определение: SimpleNamespace из модуля types - это простой класс, позволяющий создавать объекты, у которых атрибуты (свойства) можно задавать как при создании, так и потом.

  • Представление: Для создания объекта SimpleNamespace нужно импортировать его из types и передать в него именованные аргументы (или не передать их):

    from types import SimpleNamespace my_namespace = SimpleNamespace(name="John", age=30, city="New York")

  • Особенности:

    • Позволяет создавать объекты с динамическими атрибутами (похоже на словарь).

    • Удобен для создания простых объектов для хранения данных.

    • Атрибуты доступны через точку, как у обычных объектов: my_namespace.name

    • В отличие от словарей, порядок атрибутов сохраняется.

    • Поля можно менять, но нельзя добавлять новые поля

  • Примеры:

    from types import SimpleNamespace # Создание SimpleNamespace my_namespace = SimpleNamespace(name="John", age=30, city="New York") print(f"Создание SimpleNamespace: {my_namespace}") # Доступ к атрибуту print(f"Атрибут 'name': {my_namespace.name}") # Изменение атрибута my_namespace.age = 31 print(f"Изменение атрибута: {my_namespace}") # Нельзя добавить новый атрибут # my_namespace.occupation = "engineer" # Это вызовет ошибку: AttributeError: 'SimpleNamespace' object has no attribute 'occupation' # Нельзя удалить атрибут # del my_namespace.age # Это вызовет ошибку: AttributeError: age # Добавление через setattr setattr(my_namespace, "occupation", "engineer") print(f"Добавление атрибута: {my_namespace}") # Удаление через delattr delattr(my_namespace, "city") print(f"Удаление атрибута: {my_namespace}")

5. Другие структуры данных в Python:

  • Множества (Sets):

    • Неупорядоченные коллекции уникальных элементов.

    • Представление: {1, 2, 3, "apple"}

    • Изменяемые.

  • Строки (Strings):

    • Последовательность символов.

    • Представление: "hello", 'world'

    • Неизменяемые (immutable).

    • Поддерживают индексацию и многие другие операции.

  • Байтовые массивы (Bytearrays):

    • Изменяемая последовательность байтов.

    • Представление: bytearray(b"hello")

    • Используются для работы с двоичными данными.

  • Диапазоны (Ranges):

    • Последовательность целых чисел.

    • Представление: range(10), range(1, 10, 2)

    • Неизменяемые.

    • Используются для генерации последовательностей.

  • Frozen sets (неизменяемые множества)

    • Неизменяемая версия множеств (sets).

    • Представление frozenset([1, 2, 3])

Показать полностью 3

101 игра на python. Информатика. Алгоритмы сортировки

В повседневной жизни и в программировании мы сталкиваемся с необходимостью упорядочить данные. Это может быть что угодно: список покупок, книги на полке или результаты поиска. Алгоритмы сортировки – это набор инструкций, которые помогают нам расположить элементы в определенном порядке, будь то по возрастанию, убыванию или по какому-либо другому критерию.

Для примера я возьму фрукты разного размера.

Сопоставим фрукты с размерами. Будем использовать кортежи (tuple), где:

  • Первый элемент – это размер фрукта:

    • 🍎 (мелкий) – яблоко

    • 🍐 (средний) – груша

    • 🍉 (большой) – дыня

    • 🧺 (очень большой) – корзина

  • Второй элемент – это уникальный идентификатор, для работы программы.

Пример: (🍎, 1) – это мелкое яблоко с идентификатором 1.

101 игра на python. Информатика. Алгоритмы сортировки Инструкция, Программирование, Информатика, Длиннопост

Алгоритмы сортировки (сравнение по размеру фрукта):

Сортировка пузырьком (Bubble Sort):

(Более легкие пузырьки всплывают раньше)

  • Алгоритм сравнивает соседние фрукты по размеру. Если фрукт больше, чем соседний, он меняется с ним местами.

  • Этот процесс повторяется до тех пор, пока весь список фруктов не будет отсортирован от меньшего к большему.

  • Аналогия: Представь, что у тебя есть аквариум с разными по размеру пузырьками воздуха. Более легкие пузырьки (соответствующие более мелким фруктам) будут всплывать на поверхность раньше, чем более тяжелые (соответствующие более крупным фруктам). Таким образом, более легкие фрукты "всплывают" наверх списка, а тяжелые опускаются вниз.

101 игра на python. Информатика. Алгоритмы сортировки Инструкция, Программирование, Информатика, Длиннопост
101 игра на python. Информатика. Алгоритмы сортировки Инструкция, Программирование, Информатика, Длиннопост

Сортировка вставками (Insertion Sort):

  • Алгоритм строит отсортированный список, добавляя в него фрукты один за другим. Новый фрукт вставляется в нужное место, чтобы сохранить порядок по размеру.

  • Аналогия: Представь, что ты играешь в карты, и тебе нужно собрать их по порядку (например, от меньшей к большей). Ты берешь карту за картой и, как только получаешь новую карту, ты вставляешь ее на нужное место в уже собранной части карт, раздвигая другие карты, если это необходимо. Ты строишь отсортированный ряд карт, добавляя в него новые.

101 игра на python. Информатика. Алгоритмы сортировки Инструкция, Программирование, Информатика, Длиннопост
101 игра на python. Информатика. Алгоритмы сортировки Инструкция, Программирование, Информатика, Длиннопост

Сортировка выбором (Selection Sort):

  • Алгоритм находит самый маленький фрукт в неотсортированной части списка. Затем он ставит этот фрукт на первое место в неотсортированной части списка.

  • Этот процесс повторяется до тех пор, пока все фрукты не будут отсортированы.

  • Аналогия: Представь, что ты участвуешь в конкурсе на самый маленький фрукт, и тебе нужно построить ряд фруктов в порядке возрастания размера. Ты внимательно осматриваешь все фрукты и выбираешь самый маленький из них, ставишь его первым в ряд. Затем ты снова выбираешь самый маленький из оставшихся и ставишь его вторым, и так далее, пока все фрукты не будут выстроены в ряд.

101 игра на python. Информатика. Алгоритмы сортировки Инструкция, Программирование, Информатика, Длиннопост
101 игра на python. Информатика. Алгоритмы сортировки Инструкция, Программирование, Информатика, Длиннопост

101 игра на python. Информатика. Алгоритмы сортировки Инструкция, Программирование, Информатика, Длиннопост

Запустить код в google colab

Посмотреть на github

Серия «101 игра на python. Информатика»

Все серии

Удачи!

Показать полностью 8

101 игра нa python. Информатика. Системы счисления

Статья из серии 101 игра на python, где я публикую разбор кода учебного репозитория для делающих первые шаги в разработке на python и просто любителей хорошего кода. В репозитории находится сборник программ и игр, написанных лёгким языком, по которым ты можешь изучать код.

Системы Счисления


1. Абстрактная система счисления

На важно, как обoзначать числа, можно использовать любой набор символов, главное, чтобы они соответствовали прaвилам:

  • Основание (базис): Это количество уникальных символов (цифр), которые мы используем. Обозначим основание как b.

  • Цифры: Это символы, которые мы используем для представления чисел. Обычно это арабские цифры (0, 1, 2, 3, ...), латинские(I,II,II,..), но могут быть и другие символы. Например:

  • Позиция: Каждая цифра в записи числа имеет свою позицию, которая влияет на её значение.

  • Разряды: Каждая позиция называется разрядом (например, единицы, десятки, сотни и т.д.)

Как строится система счисления?

  1. Выбор основания: Выбираем целое число b, которое будет основанием нашей системы.

  2. Выбор цифр: Нам нужно b уникальных цифр. Обычно это 0, 1, 2, ..., b-1.

  3. Запись числа: Число записывается как последовательность цифр. Значение каждой цифры умножается на основание, возведенное в степень, равную ее позиции (начиная с 0 справа).

Формула для расчета значения числа:

Если у нас есть число, записанное в виде последовательности цифр dₙ dₙ₋₁ ... d₁ d₀, то его значение в десятичной системе можно вычислить по формуле:

значение = dₙ * bⁿ + dₙ₋₁ * bⁿ⁻¹ + ... + d₁ * b¹ + d₀ * b⁰

Где:

  • dᵢ - цифра в i-ом разряде

  • b - основание системы счисления

  • i - номер разряда (справа налево, начиная с 0)

Пример:

Предположим, у нас есть число 123 в десятичной системе (основание 10). По формуле:

1 * 10² + 2 * 10¹ + 3 * 10⁰ = 100 + 20 + 3 = 123

Порядки счисления (разряды):

Порядки, как мы уже говорили, это позиции цифр в числе, каждая позиция имеет свой вес, который определяется основанием в степени ее порядкового номера.

  • d₀: единицы (b⁰)

  • d₁: b (b¹)

  • d₂: b²

  • d₃: b³

  • и так далее

Правила:

  1. Диапазон цифр: Используются цифры от 0 до b-1.

  2. Позиционный принцип: Значение цифры зависит от её позиции.

  3. Переход к следующему разряду: Когда в разряде достигается значение b, происходит перенос в следующий разряд (аналог того как после 9 в десятичной системе прибавляется 1 к следующему разряду и получается 10)

Груши - яблоки:

  • 🍎 (яблоко)

  • 🍐 (груша)

  • 🍉 (дыня)

  • 🧺 (корзинка)

Правила:

  1. 3 🍎 = 1 🍐

  2. 5 🍐 = 3 🍉

  3. 2 🍉 = 1 🧺

Представление чисел:

Мы будем представлять количество фруктов в виде строки, где каждый символ юникода соответствует одному фрукту. Например, "🍎🍎🍎" - это 3 яблока, а "🍉🍉" - это 2 дыни.

Арифметические операции:

101 игра нa python. Информатика. Системы счисления Программирование, Гайд, Шпаргалка, Информатика, Яндекс Дзен (ссылка), Длиннопост
101 игра нa python. Информатика. Системы счисления Программирование, Гайд, Шпаргалка, Информатика, Яндекс Дзен (ссылка), Длиннопост
101 игра нa python. Информатика. Системы счисления Программирование, Гайд, Шпаргалка, Информатика, Яндекс Дзен (ссылка), Длиннопост

Примеры:

101 игра нa python. Информатика. Системы счисления Программирование, Гайд, Шпаргалка, Информатика, Яндекс Дзен (ссылка), Длиннопост

Разъяснение кода:

  1. normalize_fruits(fruits): Эта функция преобразует строку с фруктами к минимальному виду. Она сначала считает количество каждого фрукта, а затем, используя правила обмена, преобразует их к более крупным единицам (яблоки в груши, груши в дыни, дыни в корзины), после преобразования склеивает обратно в строку с минимальным набором фруктов.

  2. add_fruits(fruits1, fruits2): Эта функция выполняет сложение двух строк с фруктами. Она просто конкатенирует две строки и затем нормализует результат.

  3. sub_fruits(fruits1, fruits2): Это функция для вычитания одной строки фруктов из другой. Она преобразует всё в "количество яблок" и затем выполняет вычитание, а потом обратно переводит яблоки в нормализованный вид, при этом проверяет возможность вычитания.

  4. Примеры: В конце кода приведены примеры сложения и вычитания с различными комбинациями фруктов и выводом результатов.

Задания:

  1. Попробуй добавить в код функцию для умножения фруктов на целое число (например, multiply_fruits(fruits, n)).

  2. Реализуй функцию compare_fruits(fruits1, fruits2), которая сравнивает две строки с фруктами и возвращает "больше", "меньше" или "равно".

  3. Придумай свои собственные правила обмена фруктов и модифицируй код под них.

  4. Добавь проверку на корректность входных данных (чтобы строка состояла только из разрешенных символов юникода)

  5. Реализуй более продвинутое вычитание, например, не выдавать ошибку "Невозможно вычесть", а выводить результат со знаком минус (усложненное задание).


2. Конкретные системы счисления

Теперь давай рассмотрим конкретные примеры систем счисления и поработаем с ними.

2.1. Двоичная (бинарная) система (основание 2)

  • Цифры: 0, 1

  • Используется в компьютерах: Все данные в компьютерах представлены в двоичном коде (битах).

Пример:

  • Число 1011₂ (читается как "один ноль один один по основанию 2"). Перевод в десятичную систему:
    1 * 2³ + 0 * 2² + 1 * 2¹ + 1 * 2⁰ = 8 + 0 + 2 + 1 = 11₁₀

101 игра нa python. Информатика. Системы счисления Программирование, Гайд, Шпаргалка, Информатика, Яндекс Дзен (ссылка), Длиннопост

2.2. Троичная система (основание 3)

  • Цифры: 0, 1, 2

  • Интересна в теории: Применяется в некоторых областях математики и информатики.

Пример:

  • Число 210₂ (читается как "два один ноль по основанию 3"). Перевод в десятичную систему:
    2 * 3² + 1 * 3¹ + 0 * 3⁰ = 18 + 3 + 0 = 21₁₀

101 игра нa python. Информатика. Системы счисления Программирование, Гайд, Шпаргалка, Информатика, Яндекс Дзен (ссылка), Длиннопост

2.3. Семеричная система (основание 7)

  • Цифры: 0, 1, 2, 3, 4, 5, 6

  • Менее распространена: Используется в некоторых узких областях, например, в некоторых системах кодирования.

Пример:

  • Число 345₇ (читается как "три четыре пять по основанию 7"). Перевод в десятичную систему:
    3 * 7² + 4 * 7¹ + 5 * 7⁰ = 147 + 28 + 5 = 180₁₀

101 игра нa python. Информатика. Системы счисления Программирование, Гайд, Шпаргалка, Информатика, Яндекс Дзен (ссылка), Длиннопост

2.4. Десятичная система (основание 10)

  • Цифры: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

  • Повседневная: Самая распространенная система, которую мы используем каждый день.

Пример:

  • Число 789₁₀. Перевод в десятичную систему: (смысла нет, это и есть десятичное)
    7 * 10² + 8 * 10¹ + 9 * 10⁰ = 700 + 80 + 9 = 789₁₀

2.5. Шестидесятиричная система (основание 60)

  • Цифры: 0-59 (в практическом применении используются комбинации символов)

  • Историческая: Использовалась в Древнем Вавилоне, а сейчас для измерения времени (часы, минуты, секунды) и углов.

Пример:

  • Представим число 25:30:15₆₀ (25 градусов, 30 минут, 15 секунд) или
    25 * 60² + 30 * 60¹ + 15 * 60⁰ = 25 * 3600 + 30 * 60 + 15 * 1 = 90000 + 1800 + 15 = 91815₁₀ (общее число секунд)

3. Задания

Задание 1:

Переведи следующие числа из одной системы в другую:

  • 11011₂ в десятичную

  • 201₃ в десятичную

  • 563₇ в десятичную

  • 45₁₀ в двоичную

  • 34₁₀ в троичную

  • 150₁₀ в семеричную

Задание 2:

Придумай свою собственную систему счисления с основанием, например, 5 (пятеричная). Запиши несколько чисел в этой системе и переведи их в десятичную.

Задание 3:

Реализуй функции для перевода из десятичной системы в двоичную, троичную, семеричную и обратно (как в примерах выше)

Задание 4:

Напиши функцию для сложения двух двоичных чисел, представленных в виде строк. (Усложненное)

Задание 5:

Попробуй перевести какое-то время в секунды, представленное в виде "ч:м:с" в десятичную систему и обратно.

Советы:

  • Практикуйся в переводах. Чем больше ты тренируешься, тем лучше будешь понимать принципы систем счисления.

  • Не бойся экспериментировать. Попробуй создавать свои собственные системы счисления.

  • Используй Python для проверки своих решений и автоматизации перевода.

Запустить код в google colab

Посмотреть на github

Другие шпаргалки

Серия «101 игра на python»

Удачи!

Показать полностью 7

Шарите в мировой мифологии?

Проверьте себя, пройдя испытание мудрости. Самые достойные получат приз — награду в профиль на Пикабу.

Как автоматизировать работу с zakupki.gov.ru с помощью Python — просто и понятно

Эта статья написана для начинающих пользователей, которые хотят разобраться в работе сервиса отдачи информации zakupki.gov.ru. Мы шаг за шагом разберем, как получить токен для физического лица, как выглядит XML-документ для запроса и как написать простую программу на Python для взаимодействия с сервисом. Это не руководство от профессионала, а скорее дневник выживания: как не сойти с ума, пока пытаешься подружиться с сервисом zakupki.gov.ru

Как автоматизировать работу с zakupki.gov.ru с помощью Python — просто и понятно Разработка, Программа, Zakupkigovru, Python, Гайд, Программирование, Длиннопост

С 1 января 2025 года доступ к FTP-серверу zakupki.gov.ru будет закрыт, и вся информация станет доступна только через сервисы отдачи данных. До этой даты физические лица могут получать общедоступную информацию через сервис https://int44.zakupki.gov.ru/eis-integration/services/getDocsLE2 без необходимости использовать токены или электронную цифровую подпись (ЭЦП). Однако с нового года работа с сервисом потребует токенов или настройки инфраструктуры для подписания запросов ЭЦП.

Открытые данные закупок — это мощный инструмент для анализа, прозрачности государственного управления и создания полезных сервисов, как коммерческих, так и общественных. Например, на их основе можно анализировать расходы государства, выявлять нарушения или автоматизировать поиск тендеров. Ранее доступ был через FTP-сервер, сейчас данную возможность закрывают, а вместо него предлагается получать данные по протоколу SOAP. У меня нет технического образования и складывается такое ощущение, что государство хочет таким ненавязчивым способом восполнить пробелы в моих знаниях.

SOAP (Simple Object Access Protocol) — это протокол обмена данными, при котором запросы и ответы представляют собой строго структурированные XML-документы. Для многих разработчиков (включая меня) это может быть первое знакомство с этим протоколом. Более того, практическая информация по работе с SOAP и конкретно с сервисом закупок zakupki.gov.ru представлена в сети крайне ограниченно.

Структура статьи:

  1. Получение токена для работы с сервисом

  2. Структура xml-документа

  3. Пример программы на python

Получение токена для работы с сервисом

Получить токен можно следуя инструкции "ИНСТРУКЦИЯ ПО ИСПОЛЬЗОВАНИЮ СЕРВИСОВ ОТДАЧИ ИНФОРМАЦИИ ЕИС ДЛЯ ЮРИДИЧЕСКИХ И ФИЗИЧЕСКИХ ЛИЦ", размещенном на zakupki.gov.ru. Но для того, чтобы не открывать лишних окон, вкратце опишу процесс здесь:

  1. Нужно перейти по адресу: https://zakupki.gov.ru/pmd/auth/welcome (естественно через поддерживаемый браузер).

  2. Проходим авторизацию через Госуслуги, выбираем "Регистрация нового потребителя машиночитаемых данных", далее "Физическое лицо, индивидуальный предприниматель", заполняем все сведения, отправляем запрос и происходит перенаправление на новую страницу с токеном.

  3. Готово! Сохраняем токен в надежное место

Как автоматизировать работу с zakupki.gov.ru с помощью Python — просто и понятно Разработка, Программа, Zakupkigovru, Python, Гайд, Программирование, Длиннопост

Пример токена: 5d035886-82af-4f98-8a74-278bf72ff457 (был указан в инструкции, не работающий)

Структура xml-документа

Формирование правильного XML-документа — одна из главных сложностей при работе с сервисом. Любая ошибка, например, нарушение порядка тегов или отсутствие обязательного параметра, может привести к некорректному ответу сервера. Сервер либо возвращает сообщение об ошибке («Ошибка валидации полученного запроса по интеграционной схеме»), либо повторяет отправленный запрос без обработки.

Основные требования к XML-документам

  1. Порядок тегов имеет значение. Это может быть неочевидно для начинающих, но даже малейшее отклонение от порядка, описанного в интеграционной схеме, вызовет ошибку.

  2. Каждый запрос должен содержать токен. Его необходимо указывать в элементе внутри.

  3. Использование метода. Название метода запроса указывается в внутри.

  4. Обязательные параметры для каждого метода. Список обязательных параметров для каждого метода можно найти в интеграционной схеме https://int44.zakupki.gov.ru/eis-integration/services/getDocsIP?xsd=getDocsIP-ws-api.xsd

Создание идеального XML — это как готовить торт: ингредиенты строго по списку, порядок добавления важен, а итоговая структура должна быть идеальной

Поддерживаемые методы:

  • getDocsByReestrNumberRequest – запрос формирования в ХД архивов с документами по реестровому номеру

  • getDocsByOrgRegionRequest – запрос формирования в ХД архивов с документами по региону заказчика и типу документа;

  • getDocSignaturesByUrlRequest – запрос формирования в ХД архивов с подписями документов;

  • getNsiRequest – запрос в хранилище документов (ХД) данных справочника

Далее я приведу пример работающего шаблона xml документа. Все взаимодействие с сервисом происходит через url https://int44.zakupki.gov.ru/eis-integration/services/getDocsIP. Для работы с этим сервисом каждый xml файл в soapenv:Header должен содержать элемент individualPerson_token со значение вашего токена. Пример:

<soapenv:Header>
<individualPerson_token>5d035886-82af-4f98-8a74-278bf72ff457</individualPerson_token>
</soapenv:Header>

В основной части направляется название метода и структурные элементы, которые ему соответствуют. Для каждого запроса должен быть index, в котором есть id, дата создания и режим работы сервиса (TEST или PROD, но лучше сразу PROD указывать). Пример:

<index>
<id>3f227a50-418d-47ea-a3f7-e9a85f3af6e7</id>
<createDateTime>2024-12-25T16:34:29</createDateTime>
<mode>PROD</mode>
</index>

И затем в selectionParams надо указать параметры отбора файлов.
Если мы используем getDocsByReestrNumberRequest, то надо указать тип подсистемы и реестровый номер. Пример:

<selectionParams>
<subsystemType>PRIZ</subsystemType>
<reestrNumber>0888200000224000038</reestrNumber>
</selectionParams>

В целом файл для метода getDocsByOrgRegionRequest будет выглядеть следующим образом:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://zakupki.gov.ru/fz44/get-docs-ip/ws">
<soapenv:Header>
<individualPerson_token>5d035886-82af-4f98-8a74-278bf72ff457</individualPerson_token> <!-- Здесь должен быть указан ваш токен -->
</soapenv:Header>
<soapenv:Body>
<ws:getDocsByOrgRegionRequest> <!-- Здесь указывается метод -->
<index> <!-- index принцип формирования был приведен ранее -->
<id>3f227a50-418d-47ea-a3f7-e9a85f3af6e7</id>
<createDateTime>2024-12-25T16:34:29</createDateTime>
<mode>PROD</mode>
</index>
<selectionParams> <!-- обратите внимание, для каждого метода будут свои параметры отбора, перечисленные в интеграционной схеме. Сохранение порядка параметров обязательно! -->
<subsystemType>PRIZ</subsystemType>
<reestrNumber>0888200000224000038</reestrNumber>
</selectionParams>
</ws:getDocsByOrgRegionRequest>
</soapenv:Body>
</soapenv:Envelope>

Для каждого метода существуют свои обязательные поля. Подробнее посмотреть обязательные параметры можно тут: https://int44.zakupki.gov.ru/eis-integration/services/getDocsIP?xsd=getDocsIP-ws-api.xsd. Порядок параметров важен!

Например, для метода getDocsByOrgRegionRequest я перепутал порядок и сначала у меня стоял subsystemType, а затем orgRegion и сервер выдавал ошибку несоответствия запросу интеграционной схеме. Пример правильного xml файла для этого метода:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://zakupki.gov.ru/fz44/get-docs-ip/ws">
<soapenv:Header>
<individualPerson_token>5d035886-82af-4f98-8a74-278bf72ff457</individualPerson_token>
</soapenv:Header>
<soapenv:Body>
<ws:getDocsByOrgRegionRequest>
<index>
<id>3f227a50-418d-47ea-a3f7-e9a85f3af6e8</id>
<createDateTime>2024-12-25T16:38:45</createDateTime>
<mode>PROD</mode>
</index>
<selectionParams>
<orgRegion>72</orgRegion>
<subsystemType>PRIZ</subsystemType>
<documentType44>epNotificationEF2020</documentType44>
<periodInfo>
<exactDate>2024-12-24</exactDate>
</periodInfo>
</selectionParams>
</ws:getDocsByOrgRegionRequest>
</soapenv:Body>
</soapenv:Envelope>

Пример программы на Python

Для отправки запроса и получения результата мы будем использовать python.
Для начала импортируем библиотеки, которые пригодятся в будущем:

import uuid
import datetime
import os
import requests
import xmltodict

Для автоматизированной отправки запросов для метода , сформируем шаблон xml файла, в котором будут автоматически из кода подставляться токен, ID и время запроса и назовем его test.xml:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://zakupki.gov.ru/fz44/get-docs-le/ws">
<soapenv:Header>
<individualPerson_token>{{ token }}</individualPerson_token>
</soapenv:Header>
<soapenv:Body>
<ws:getDocsByReestrNumberRequest>
<index>
<id>{{ UUID }}</id>
<createDateTime>{{ created_time }}</createDateTime>
<mode>PROD</mode>
</index>
<selectionParams>
<subsystemType>PRIZ</subsystemType>
<reestrNumber>0888200000224000038</reestrNumber>
</selectionParams>
</ws:getDocsByReestrNumberRequest>
</soapenv:Body>
</soapenv:Envelope>

Теперь нам надо получить заполненный шаблон:

file_path = 'test.xml' # расположение файла-шаблона
token = '5d035886-82af-4f98-8a74-278bf72ff457' # вставьте сюда ваше токен

with open(file_path, 'r', encoding='utf-8') as file:
xml_content = file.read()
generated_uuid = str(uuid.uuid4()) # уникальный id для запроса
generated_datetime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%dT%H:%M:%S') # текущая дата
xml_data = xml_content.replace("{{ UUID }}", generated_uuid).replace("{{ created_time }}", generated_datetime).replace("{{ token }}", token) # заполнение шаблона

Далее нам остается только отправить данные на сервер:

url = 'https://int44.zakupki.gov.ru/eis-integration/services/getDoc...'
headers = {
'Content-Type': 'text/xml; charset=utf-8',
}
response = requests.post(url, data=xml_data, headers=headers, timeout=30)

В ответ мы получаем xml файл, в котором есть ссылка на архив. Пример ответа:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header/>
<soap:Body>
<ns2:getDocsByOrgRegionResponse xmlns:ns2="http://zakupki.gov.ru/fz44/get-docs-ip/ws">
<index>
<id>8e5e2386-c1e9-499c-88e8-f23313667472</id>
<refId>e4858318-62c6-41c0-99a5-879cdc103b39</refId>
<createDateTime>2024-12-25T14:42:25.180</createDateTime>
<mode>PROD</mode>
</index>
<dataInfo>
<archiveUrl>ССЫЛКА</archiveUrl>
</dataInfo>
</ns2:getDocsByOrgRegionResponse>
</soap:Body></soap:Envelope>

Для парсинга xml воспользуемся библиотекой xmltodict и получим url архива:

response_content = xmltodict.parse(response.content)
url_archive = response_content['soap:Envelope']['soap:Body']['ns2:getDocsByOrgRegionResponse']['dataInfo']['archiveUrl']

Далее не совсем очевидный момент, который не отражен в инструкции. Для скачивания архива, нам также потребуется отправлять токен. Я долго не мог понять, почему архив так долго готовится и его нельзя скачать, пока не заметил, что в примере в инструкции в headers отправляется токен:

Как автоматизировать работу с zakupki.gov.ru с помощью Python — просто и понятно Разработка, Программа, Zakupkigovru, Python, Гайд, Программирование, Длиннопост

подчеркивание - это моя работа :)

В самой инструкции об этом не слова и на мой взгляд это большое упущение. На python данный запрос будет выглядеть так:

headers = {
'individualPerson_token': token
}
response_get_archive = requests.get(url_archive, headers=headers, timeout=120)

И далее нам остается только сохранить архив:

with open('archive.zip', 'wb') as f:
f.write(response_get_archive.content)

Полный код программы:

import uuid
import datetime
import os
import requests
import xmltodict

file_path = 'test.xml'
token = '5d035886-82af-4f98-8a74-278bf72ff457' # вставьте сюда ваше токен

with open(file_path, 'r', encoding='utf-8') as file:
xml_content = file.read()
generated_uuid = str(uuid.uuid4())
generated_datetime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%dT%H:%M:%S')
xml_data = xml_content.replace("{{ UUID }}", generated_uuid).replace("{{ created_time }}", generated_datetime).replace("{{ token }}", token)


url = 'https://int44.zakupki.gov.ru/eis-integration/services/getDoc...'
headers = {
'Content-Type': 'text/xml; charset=utf-8',
}
response = requests.post(url, data=xml_data, headers=headers, timeout=30)

response_content = xmltodict.parse(response.content)
url_archive = response_content['soap:Envelope']['soap:Body']['ns2:getDocsByOrgRegionResponse']['dataInfo']['archiveUrl']
headers = {
'individualPerson_token': token
}
response_get_archive = requests.get(url_archive, headers=headers, timeout=120)

with open('archive.zip', 'wb') as f:
f.write(response_get_archive.content)

Надеюсь данная статья послужит толчком для изучения протокола работы с SOAP и поможет разобраться с сервисом отдачи информации и документов zakupki.gov.ru

Показать полностью 3

101 игра на python. Виселица. Игра в слова

101 игра на python. Виселица. Игра в слова Программа, Гайд, Программирование, Игра в слова, Длиннопост, Python, Яндекс Дзен (ссылка)

Статья из серии 101 игра на python. В серии я публикую разбор кода учебного репозитория для делающих первые шаги в разработке на python и просто любителей хорошего кода. В репозитории находится сборник программ игр, написанных лёгким языком, по которым ты можешь изучать код.


Игра "Виселица" - это игра в слова, где один игрок (или компьютер) загадывает слово, а другой игрок пытается его отгадать по буквам.

За каждую неправильную букву игрок получает штраф в виде части рисунка виселицы. Если рисунок завершен, игрок проигрывает.

Правила игры:
1. Компьютер выбирает случайное слово из заранее определенного списка.
2. Игрок видит слово, представленное прочерками (по одной на каждую букву).
3. Игрок пытается отгадать слово, вводя буквы.
4. Если введенная буква есть в слове, она отображается на своих местах.
5. Если введенной буквы нет в слове, игрок получает штраф.
6. Игра продолжается до тех пор, пока игрок не угадает слово или не исчерпает лимит штрафов.


Алгоритм


1. Инициализировать массив слов, которые может загадать компьютер.
2. Выбрать случайное слово из массива.
3. Создать строку `GUESS$` , состоящую из прочерков, по длине загаданного слова.
4. Инициализировать число ошибок, равное 0.
5. Начать цикл "пока слово не отгадано и количество ошибок меньше 6":
5.1 Запросить ввод буквы от игрока.
5.2 Если введенная буква есть в загаданном слове
5.2.1 Обновить строку `GUESS$` , показав букву на всех ее позициях в слове.
5.2.2 Если все буквы отгаданы, перейти к шагу 6.
5.3 Иначе
5.3.1 Увеличить число ошибок на 1.
5.3.2 Показать изображение виселицы, соответствующее текущему количеству ошибок
5.4 Если число ошибок равно 6, перейти к шагу 7.
6. Вывести сообщение "YOU GOT IT!", затем загаданное слово, и перейти к шагу 8.
7. Вывести сообщение "SORRY, YOU DIDN'T GET IT.", затем загаданное слово, и перейти к шагу 8.
8. Конец игры.

Блок-схема

101 игра на python. Виселица. Игра в слова Программа, Гайд, Программирование, Игра в слова, Длиннопост, Python, Яндекс Дзен (ссылка)

Legenda:

- Start - Начало игры.
- InitializeWords - Инициализация списка слов для выбора.
- ChooseWord - Выбор случайного слова из списка.
- CreateGuessString - Создание строки `guessString` из прочерков, соответствующей длине загаданного слова.
- InitializeErrors - Инициализация счетчика ошибок `numberOfErrors` в 0.
- LoopStart - Начало цикла, который продолжается, пока слово не угадано и количество ошибок меньше 6.
- InputLetter - Запрос у пользователя ввода буквы и сохранение ее в `userLetter`.
- CheckLetter - Проверка, есть ли введенная буква `userLetter` в загаданном слове `targetWord`.
- UpdateGuessString - Обновление строки `guessString`, показывая введенную букву на ее местах.
- CheckWin - Проверка, угадано ли слово (т.е. `guessString` равен `targetWord`).
- OutputWin - Вывод сообщения о победе "YOU GOT IT!" и загаданного слова.
- End - Конец игры.
- IncreaseErrors - Увеличение счетчика ошибок `numberOfErrors` на 1.
- DrawHangman - Отображение текущего состояния виселицы в зависимости от количества ошибок.
- CheckLose - Проверка, достигло ли количество ошибок `numberOfErrors` значения 6.
- OutputLose - Вывод сообщения о проигрыше "SORRY, YOU DIDN'T GET IT." и загаданного слова.


Код.

список слов

101 игра на python. Виселица. Игра в слова Программа, Гайд, Программирование, Игра в слова, Длиннопост, Python, Яндекс Дзен (ссылка)


список состояний виселицы

101 игра на python. Виселица. Игра в слова Программа, Гайд, Программирование, Игра в слова, Длиннопост, Python, Яндекс Дзен (ссылка)

Основная логика

101 игра на python. Виселица. Игра в слова Программа, Гайд, Программирование, Игра в слова, Длиннопост, Python, Яндекс Дзен (ссылка)

Разбор кода:

1. Импорт модуля `random`
- `import random`: Импортирует модуль random для случайного выбора слова.


2. Список слов `WORDS`: Список, содержащий слова, из которых компьютер выбирает слово для игры.


3. Функция `draw_hangman(errors)`
- Отображает состояние виселицы в зависимости от количества ошибок, используя ASCII-арт.
- `hangman_stages` - массив строк, представляющих стадии виселицы.
- `print(hangman_stages[errors])` - выводит на экран соответсвующую строку.


4. Функция `play_hangman()`:
- Выбор слова:
- `target_word = random.choice(WORDS).upper()`: Случайно выбирает слово из списка `WORDS` и переводит его в верхний регистр.


- Создание строки для отгадывания:
- `guess_string = "_" * len(target_word)`: Создает строку, состоящую из прочерков, длина которой соответствует длине загаданного слова.


- Инициализация счетчика ошибок:
- `number_of_errors = 0`: Устанавливает начальное количество ошибок в 0.


- Основной цикл игры `while number_of_errors < 6 and "_" in guess_string:
- Цикл продолжается, пока количество ошибок меньше 6 и в строке `guess_string` есть прочерки (т.е. пока слово не угадано и не исчерпан лимит ошибок).
- `print("Слово:", guess_string)`: Выводит текущее состояние слова с угаданными буквами и прочерками.
- `user_letter = input("Введите букву: ").upper()`: Запрашивает у пользователя ввод буквы и переводит ее в верхний регистр.


- Проверка наличия буквы в слове:
- `if user_letter in target_word:`: Проверяет, есть ли введенная буква в загаданном слове.


- Если буква есть:
- `new_guess_string = ""`: Создает пустую строку `new_guess_string` для сборки нового варианта отгадываемого слова.
- Цикл `for i in range(len(target_word))` перебирает все символы в загаданном слове.
- Если текущая буква в загаданном слове совпадает с введенной буквой `user_letter`, то добавляет ее в `new_guess_string`, иначе, добавляет символ с текущей позиции из `guess_string`.
- `guess_string = new_guess_string`: Обновляет `guess_string` новым вариантом с угаданными буквами.
- `if guess_string == target_word:`: Проверяет, угадано ли слово.
- `print("ПОЗДРАВЛЯЮ! Вы угадали слово:", target_word)`: Выводит поздравление и загаданное слово.
- `return`: Завершает функцию (игру).


- Если буквы нет в слове:
- `number_of_errors += 1`: Увеличивает счетчик ошибок на 1.
- `draw_hangman(number_of_errors)`: Вызывает функцию `draw_hangman` для отображения виселицы.


- Проверка на проигрыш:
- `if number_of_errors == 6:`: Проверяет, равно ли количество ошибок 6.
- `print("СОЖАЛЕЮ, вы не отгадали слово. Загаданное слово:", target_word)`: Выводит сообщение о проигрыше и загаданное слово.


5. Запуск игры:
- `if __name__ == "__main__":`: Этот блок гарантирует, что функция `play_hangman()` будет запущена, только если файл исполняется напрямую, а не импортируется как модуль.
- `play_hangman()`: Вызывает функцию для начала игры.

Репозиторий
Код
Запустить эту программу ты можешь в google colab

Посмотри и другие статьи

Удачи!

Показать полностью 5

101 игра нa python. Шпаргалка. Переменные в Python: что, как и зачем нужны

Статья из серии 101 игра на python. В серии я публикую разбор кода учебного репозитория для делающих первые шаги в разработке на python и просто любителей хорошего кода. В репозитории находится сборник программ игр, написанных лёгким языком, по которым ты можешь изучать код.

Переменные — это именованные контейнеры для хранения данных в памяти компьютера. Они позволяют обращаться к данным по имени, вместо того чтобы использовать их непосредственно.

101 игра нa python. Шпаргалка. Переменные в Python: что, как и зачем нужны Гайд, Программирование, Инструкция, Длиннопост, Шпаргалка, Python, Яндекс Дзен (ссылка)

Здесь `x` и `y` — переменные. `x` хранит число 10, а `y` — строку 'Привет, мир!'.

Как работают переменные в Python?

1. Динамическая типизация

В Python не нужно указывать тип переменной при её создании — это делается автоматически.

101 игра нa python. Шпаргалка. Переменные в Python: что, как и зачем нужны Гайд, Программирование, Инструкция, Длиннопост, Шпаргалка, Python, Яндекс Дзен (ссылка)

2. Ссылочная модель хранения данных

Переменные в Python — это ссылки на объекты в памяти. Например:

101 игра нa python. Шпаргалка. Переменные в Python: что, как и зачем нужны Гайд, Программирование, Инструкция, Длиннопост, Шпаргалка, Python, Яндекс Дзен (ссылка)

Правила именования переменных

1.Обязательные правила

- Имя переменной может состоять из букв, цифр и символа `_`, но не может начинаться с цифры.

✅ Примеры: `my_var`, `_data`, `var123`

❌ Неправильно: `123var`, `my-var`

- Имя переменной чувствительно к регистру.

Пример: `age` и `Age` — это разные переменные.

2. Рекомендации для имён переменных:

- Используй имена, которые отражают суть данных.

❌ Плохо: `a = 100`, `b = 'Имя'`

✅ Хорошо: `salary = 100`, `username = 'Имя'`

- Для многословных имён используй стиль snake_case:

Пример: `user_age`, `total_cost`.

3. Зарезервированные слова

Нельзя использовать ключевые слова Python (например, `if`, `for`, `while`) в качестве имён переменных. Чтобы увидеть список ключевых слов, выполни:

101 игра нa python. Шпаргалка. Переменные в Python: что, как и зачем нужны Гайд, Программирование, Инструкция, Длиннопост, Шпаргалка, Python, Яндекс Дзен (ссылка)

Особенности хранения типов данных

1. Типы данных Python

101 игра нa python. Шпаргалка. Переменные в Python: что, как и зачем нужны Гайд, Программирование, Инструкция, Длиннопост, Шпаргалка, Python, Яндекс Дзен (ссылка)

2. Изменяемые и неизменяемые типы

- Изменяемые: `list`, `dict`, `set`.

101 игра нa python. Шпаргалка. Переменные в Python: что, как и зачем нужны Гайд, Программирование, Инструкция, Длиннопост, Шпаргалка, Python, Яндекс Дзен (ссылка)

- Неизменяемые `int`, `float`, `str`, `tuple`.

101 игра нa python. Шпаргалка. Переменные в Python: что, как и зачем нужны Гайд, Программирование, Инструкция, Длиннопост, Шпаргалка, Python, Яндекс Дзен (ссылка)

3. Функция `type` для проверки типа

101 игра нa python. Шпаргалка. Переменные в Python: что, как и зачем нужны Гайд, Программирование, Инструкция, Длиннопост, Шпаргалка, Python, Яндекс Дзен (ссылка)

1. Используй осмысленные имена переменных, чтобы твой код был понятным.

2. Помни, что Python не требует объявления типа переменной, но будь внимателен, чтобы не путаться с типами данных.

3. Изучи встроенные функции работы с переменными, такие как `type()`, `id()` и модули, такие как `sys`, чтобы лучше понимать, как Python управляет памятью.

Показать полностью 7

101 игра на python. Шпаргалка. Строки в python


Статья из сборника 101 игра на python. В сборнике я публикую разбор кода учебного репозитория для делающих первые шаги в разработке на python и просто любителей хорошего кода. В репозитории находится сборник программ игр, написанных лёгким языком, по которым ты можешь изучать код.


В Python строки являются одним из самых важных и часто используемых типов данных. Вот краткий обзор различных типов строк и их особенностей:

Обычные строки

Обычная строка создается с помощью одинарных `'` или двойных кавычек `"`.

101 игра на python. Шпаргалка. Строки в python Гайд, Программирование, Инструкция, Шпаргалка, Яндекс Дзен (ссылка), Длиннопост

Они одинаковы, но важно быть последовательным в использовании одного стиля.

---

Многострочные строки

Многострочные строки заключаются в тройные кавычки `'''` или `"""`. Они позволяют писать текст на нескольких строках.

101 игра на python. Шпаргалка. Строки в python Гайд, Программирование, Инструкция, Шпаргалка, Яндекс Дзен (ссылка), Длиннопост

f-строки (форматированные строки)

f-строки (или форматированные строки) используются для вставки значений переменных и выражений прямо внутрь строки. Перед началом строки добавляется символ `f`.

101 игра на python. Шпаргалка. Строки в python Гайд, Программирование, Инструкция, Шпаргалка, Яндекс Дзен (ссылка), Длиннопост

Преимущество f-строк в том, что они просты и читаемы.

В новых версиях Python (начиная с 3.8) появилась удобная возможность использовать выражение вида `f'{name=}'` в f-строках. Эта конструкция выводит не только значение переменной, но и её имя, что особенно полезно для отладки.

101 игра на python. Шпаргалка. Строки в python Гайд, Программирование, Инструкция, Шпаргалка, Яндекс Дзен (ссылка), Длиннопост

r-строки (сырые строки)

Вr-строки (raw strings) создаются добавлением символа `r` перед строкой. Они используются для работы с символами, которые обычно интерпретируются как специальные, например, символы переноса строки (`\n`) или табуляции (`\t`).

101 игра на python. Шпаргалка. Строки в python Гайд, Программирование, Инструкция, Шпаргалка, Яндекс Дзен (ссылка), Длиннопост

Без `r` эта строка была бы интерпретирована с заменой `\n` на перенос строки.

u-строки (Unicode строки)

u-строки были важны в Python 2 для работы с Unicode, но в Python 3 строки по умолчанию являются Unicode, поэтому добавление `u` уже необязательно.

101 игра на python. Шпаргалка. Строки в python Гайд, Программирование, Инструкция, Шпаргалка, Яндекс Дзен (ссылка), Длиннопост

b-строки (байтовые строки)

Байтовые строки используются для работы с бинарными данными. Такие строки начинаются с `b`. Они не поддерживают Unicode-символы, только байты.

101 игра на python. Шпаргалка. Строки в python Гайд, Программирование, Инструкция, Шпаргалка, Яндекс Дзен (ссылка), Длиннопост

Строки с экранированием

Чтобы включить специальные символы в строку, используются экранирующие последовательности с обратным слэшем (`\`).

101 игра на python. Шпаргалка. Строки в python Гайд, Программирование, Инструкция, Шпаргалка, Яндекс Дзен (ссылка), Длиннопост

Комбинация f-строк и r-строк

Можно комбинировать типы строк. Например, f-строки и сырые строки:

101 игра на python. Шпаргалка. Строки в python Гайд, Программирование, Инструкция, Шпаргалка, Яндекс Дзен (ссылка), Длиннопост

Выбор типа строки зависит от задачи:

- Для обычного текста — `'` или `"`.

- Для многострочного текста — `'''` или `"""`.

- Для подстановки значений — `f`.

- Для путей или регулярных выражений — `r`.

- Для бинарных данных — `b`.

Показать полностью 8

101 игра на python. ACEDU - Симулятор карточной игры

101 игра на python. ACEDU - Симулятор карточной игры Программирование, Гайд, Длиннопост

Продолжаю портировать игры из книги 101 Basic Computer Games (и добавлять свои)


Этот репозиторий создан как для начинающих делать первые шаги в программировании, так и для любителей хорошего кода . Здесь я собираю программы, проверенные временем из легендарной книги «101 Basic Computer Games» и добавляю свои идеи. В частности, к большинству игр я делаю версии для работы с моделями машинного обучения. Если тебе интересно - подпишись, чтобы не пропустить что-то интересное

Серия: 👉 101 игра на python


Сегодняшний код - симуляция простой карточной игры.


Игрок делает ставки, основываясь на вероятности того, что следующая карта окажется между двумя уже открытыми.

- Начальный капитал. Игрок начинает с 100 долларов.

- Правила игры:

1. Компьютер выкладывает две карты.

2. Игрок может решить, сделать ставку или нет.

3. Если ставка сделана, открывается третья карта.

4. Если значение третьей карты лежит между первыми двумя картами, игрок выигрывает ставку. В противном случае, ставка проигрывается.

- Игра заканчивается, когда игрок теряет весь капитал или вручную завершает её.

101 игра на python. ACEDU - Симулятор карточной игры Программирование, Гайд, Длиннопост

Описание работы здесь

код здесь

Запустить можешь здесь

Удачи!

Показать полностью 2
Отличная работа, все прочитано!