Kodduu Python
1.08K subscribers
311 photos
28 videos
186 links
Научись программировать на Python на интересных примерах

Самый быстрый курс https://stepik.org/a/187914
Самый нескучный курс https://stepik.org/a/185238

Во вопросам сотрудничества: @AlexErf
Download Telegram
Я добавил функцию для декодирования сообщения. Теперь код может раскодировать сообщение, используя упрощённые правила. Запусти обновлённый скрипт, чтобы проверить результат! 🚀


import random

# Основные элементы инопланетного языка
base_symbols = ["@", "#", "$", "%", "&", "*"] # "Символы" как атомарные элементы
colors = ["красный", "синий", "зелёный", "жёлтый", "чёрный"] # Ассоциированные цвета
modifications = ["растяжение", "сжатие", "импульс", "эхо"] # Динамические правила

# Генерация базового "слова"
def generate_base_word():
length = random.randint(3, 6) # Длина слова
return "".join(random.choice(base_symbols) for _ in range(length))

# Применение цвета
def apply_color(word):
color = random.choice(colors)
return f"{color} {word}"

# Применение модификации
def apply_modification(word):
modification = random.choice(modifications)
if modification == "растяжение":
word = word + "-" * random.randint(1, 3)
elif modification == "сжатие":
word = word[:random.randint(1, len(word) - 1)]
elif modification == "импульс":
word = f"{word}~"
elif modification == "эхо":
word = word + word[::-1] # Добавление зеркального слова
return f"{modification}: {word}"

# Кодирование сообщения
message = "С Новым 2025 годом!"
encoded_message = []
coding_map = {} # Карта соответствия символов

for char in message:
if char.strip(): # Пропускаем пробелы и пустые символы
base_word = generate_base_word()
colored_word = apply_color(base_word)
modified_word = apply_modification(colored_word)
encoded_message.append(modified_word)
coding_map[modified_word] = char # Сохраняем соответствие символа и кодировки
else:
encoded_message.append("пробел")
coding_map["пробел"] = " "

# Вывод закодированного сообщения
print("Закодированное сообщение:")
for encoded_word in encoded_message:
print(encoded_word)

# Раскодирование сообщения
def decode_message(encoded_message, coding_map):
decoded_message = []
for encoded_word in encoded_message:
decoded_message.append(coding_map.get(encoded_word, "?")) # Используем карту для точного восстановления
return "".join(decoded_message)

# Пример декодирования
print("\nДекодированное сообщение:")
decoded_message = decode_message(encoded_message, coding_map)
print(decoded_message)


Подпишись 👉🏻 @KodduuPython 🤖
👍5
👉👉👉 Зимняя акция -40% на профессию Python-разрботчик с трудоустройством от нашего партнера GeekBrains ❄️❄️❄️

В курс включены:

👉 Все основы Python
👉 Высокоуровневый веб-фреймворк Django
👉 Продвинутые темы (Flask, CI/CD, REST API, многозадачность, безопасность и т.д.)
👉 Работы с реляционными базами данных SQL

Плюс сертификат государственного образца. Есть три уровня обучения и возможность платить помесячно.

👉👉👉 Количество мест ограничено 🏃🏃‍♀️

👉👉👉 Забрать скидку тут 🔥🔥🔥

Реклама. Информация о рекламодателе по ссылкам в посте.
👍2
Как поднять свой chatGPT?

На начало 2025 года одной из популярных тем является использование генеративного AI для текстов, изображений и кода с помощью библиотек, таких как OpenAI, Hugging Face и Stability AI. Вот пример кода на Python, который использует библиотеку Hugging Face Transformers для генерации текста:

### Код: Генерация текста с использованием модели GPT


from transformers import AutoTokenizer, AutoModelForCausalLM

# Загрузка токенайзера и модели
model_name = "gpt2" # Вы можете использовать более продвинутую модель, например, "gpt-neo" или "gpt-j"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

# Начальная строка текста
prompt = "In the year 2025, artificial intelligence"

# Подготовка входных данных
input_ids = tokenizer.encode(prompt, return_tensors="pt")

# Генерация текста
output = model.generate(
input_ids,
max_length=50, # Максимальная длина текста
num_return_sequences=1, # Количество генерируемых текстов
temperature=0.7, # "Креативность" текста (0.7 - сбалансированное значение)
top_k=50, # Фильтрация вероятностей (top-k sampling)
top_p=0.9, # Нуклеус-сэмплирование (top-p sampling)
do_sample=True, # Включение сэмплирования
)

# Декодирование и вывод текста
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print("Generated Text:\n", generated_text)


### Что делает этот код:
1. Загружает предобученную языковую модель (GPT-2 в данном случае).
2. Принимает начальную строку текста (`prompt`) для создания контекста.
3. Генерирует продолжение текста на основе введенного промпта.
4. Настраивает параметры генерации, чтобы управлять креативностью и качеством.

### Как улучшить:
- Использовать более мощные модели, такие как GPT-4 (если есть доступ через API).
- Включить дообучение модели на собственных данных.
- Интегрировать код в веб-приложение или чат-бота для интерактивности.

❗️ Для работы код потребует установки и конфигурации библиотек по интсрукции https://pytorch.org/get-started/locally/. Плюс место для самой модели chatGPT2.

👉 Попробуйте поменять prompt в коде для получения других отвтеов, либо допишиет код, чтобы он принимал prompy с ввода.

Подпишись 👉🏻 @KodduuPython 🤖
3
Вот обновленный код, который принимает prompt из консоли + пофишены проблемы с tokens:


from transformers import AutoTokenizer, AutoModelForCausalLM

# Загрузка токенайзера и модели
model_name = "gpt2" # Вы можете заменить на более продвинутую модель
print("Loading model...")
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
print("Model loaded.")

# Установка pad_token_id, если он отсутствует
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token

# Получение prompt из консоли
prompt = input("Enter your prompt: ")
if not prompt.strip():
print("Prompt cannot be empty!")
exit()

# Подготовка входных данных
input_ids = tokenizer.encode(prompt, return_tensors="pt")
attention_mask = input_ids.ne(tokenizer.pad_token_id).long() # Создание attention mask

# Генерация текста
print("Generating text...")
output = model.generate(
input_ids,
attention_mask=attention_mask, # Передача attention_mask
max_length=50, # Максимальная длина текста
num_return_sequences=1, # Количество генерируемых текстов
temperature=0.7, # "Креативность" текста
top_k=50, # Фильтрация вероятностей (top-k sampling)
top_p=0.9, # Нуклеус-сэмплирование (top-p sampling)
do_sample=True, # Включение сэмплирования
pad_token_id=tokenizer.pad_token_id, # Установка токена-заполнителя
)

# Декодирование и вывод текста
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print("\nGenerated Text:\n", generated_text)


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

Подпишись 👉🏻 @KodduuPython 🤖
👍21
Обучение модели на собственной Wiki можно организовать с использованием библиотеки Hugging Face Transformers. Вот общий план, как это сделать:

---

### 1. Подготовка данных
#### Шаги:
1. Соберите данные:
- Экспортируйте содержимое вашей Wiki в текстовый формат (например, .txt, .json, или `.csv`).
- Убедитесь, что текст чистый: удалите разметку, HTML-теги, ненужные символы.

2. Форматируйте данные:
- Для обучения лучше всего использовать формат, где каждая строка представляет отдельный пример:

Article 1 content...
Article 2 content...


#### Пример:
Если у вас данные в JSON:

[
{"title": "Article 1", "content": "Content of article 1"},
{"title": "Article 2", "content": "Content of article 2"}
]

Превратите это в простой текстовый файл:

import json

with open("wiki.json") as f:
data = json.load(f)

with open("wiki_texts.txt", "w") as f:
for item in data:
f.write(item["content"] + "\n")


---

### 2. Выберите модель
- Используйте предобученную модель (например, gpt2, bert, или `t5`), которую можно дообучить на ваших данных.

---

### 3. Установите библиотеки
Убедитесь, что установлены все необходимые библиотеки:

pip install transformers datasets


---

### 4. Создайте скрипт для дообучения
Вот пример дообучения модели GPT-2:


from transformers import AutoTokenizer, AutoModelForCausalLM, Trainer, TrainingArguments
from datasets import load_dataset

# Шаг 1: Загрузка данных
dataset = load_dataset("text", data_files={"train": "wiki_texts.txt"})

# Шаг 2: Загрузка модели и токенайзера
model_name = "gpt2" # Или любая другая предобученная модель
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

# Шаг 3: Токенизация данных
def tokenize_function(examples):
return tokenizer(examples["text"], truncation=True, padding="max_length", max_length=512)

tokenized_dataset = dataset.map(tokenize_function, batched=True)

# Шаг 4: Настройка аргументов обучения
training_args = TrainingArguments(
output_dir="./results",
overwrite_output_dir=True,
num_train_epochs=3,
per_device_train_batch_size=4,
save_steps=10_000,
save_total_limit=2,
prediction_loss_only=True
)

# Шаг 5: Создание Trainer
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_dataset["train"],
)

# Шаг 6: Запуск обучения
trainer.train()

# Сохранение модели
trainer.save_model("./fine_tuned_model")
tokenizer.save_pretrained("./fine_tuned_model")


---

### 5. Тестирование модели
После дообучения протестируйте модель на ваших данных:

from transformers import AutoTokenizer, AutoModelForCausalLM

model_path = "./fine_tuned_model"
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(model_path)

prompt = "What is the purpose of this Wiki?"
input_ids = tokenizer.encode(prompt, return_tensors="pt")

output = model.generate(input_ids, max_length=50, num_return_sequences=1, temperature=0.7)
print(tokenizer.decode(output[0], skip_special_tokens=True))


---

### 6. Дополнительные рекомендации
1. Объем данных:
- Для значительных улучшений вам потребуется большой объем текстов.
- Если данных мало, используйте методы дообучения с регуляризацией, такие как LoRA или Adapter Layers.

2. Выбор модели:
- Для более структурированных текстов можно попробовать модели, такие как T5 или BERT.

3. Разделение на тренировочные и валидационные данные:
- Важно выделить часть данных (например, 10-20%) для проверки качества модели.

4. Инфраструктура:
- Для обучения потребуется GPU. Локально можно использовать CUDA, или обратиться к облачным сервисам, таким как Google Colab или AWS.

Подпишись 👉🏻 @KodduuPython 🤖
👍41
Для тех кому интересен еще и JavaScript - скидка до 31 января на наш stepik курс JavaScript: самый быстрый курс 🔥🔥🔥

Подпишись 👉🏻 @KodduuPython 🤖
Код демонстрирует использование различных возможностей высокоуровневой типизации в Python, включая Callable, Union, Optional, Tuple, List и Any. Эти инструменты делают код более читаемым и безопасным благодаря четкому определению ожидаемых типов данных.


# Демонстрация использования функций высокоуровневой типизации в Python
from typing import Callable, List, Tuple, Union, Optional, Any

# 1. Callable: Описание функций как аргументов
# Функция принимает другую функцию и число, возвращает результат вызова функции

def apply_function(func: Callable[[int], int], value: int) -> int:
"""Применяет переданную функцию к значению."""
print(f"Applying function to {value}")
return func(value)

# Пример использования

def increment(x: int) -> int:
return x + 1

result = apply_function(increment, 5)
print(f"Result: {result}") # Result: 6

# 2. Union: Параметр может быть нескольких типов

def parse_input(value: Union[int, str]) -> str:
"""Преобразует значение в строку."""
if isinstance(value, int):
return f"Integer: {value}"
return f"String: {value}"

print(parse_input(42)) # Integer: 42
print(parse_input("Hello")) # String: Hello

# 3. Optional: Тип может быть None

def describe_item(item: Optional[str]) -> str:
"""Возвращает описание элемента."""
if item is None:
return "No item provided"
return f"Item: {item}"

print(describe_item("Book")) # Item: Book
print(describe_item(None)) # No item provided

# 4. Tuple: Фиксированный набор типов

def get_coordinates() -> Tuple[float, float]:
"""Возвращает координаты."""
return (42.0, -71.0)

coordinates = get_coordinates()
print(f"Coordinates: {coordinates}") # Coordinates: (42.0, -71.0)

# 5. List: Список элементов одного типа

def square_numbers(numbers: List[int]) -> List[int]:
"""Возвращает список квадратов чисел."""
return [x ** 2 for x in numbers]

squares = square_numbers([1, 2, 3, 4])
print(f"Squares: {squares}") # Squares: [1, 4, 9, 16]

# 6. Any: Общий тип для произвольных объектов

def echo(value: Any) -> Any:
"""Возвращает значение как есть."""
return value

print(echo(123)) # 123
print(echo("Dynamic typing!")) # Dynamic typing!


Подпишись 👉🏻 @KodduuPython 🤖
3👍1
Код демонстрирует использование операторов объединения словарей | и |= в Python 3.9 и новее.

Оператор | создает новый словарь, объединяя ключи и значения из двух словарей. Если ключи совпадают, приоритет имеет значение из правого словаря.
Оператор |= изменяет существующий словарь, добавляя или заменяя ключи и значения из другого словаря.


# Демонстрация использования операторов объединения словарей в Python

# Операторы объединения словарей (Python 3.9+) позволяют легко объединять два словаря.
# Оператор `|` возвращает новый словарь, объединяя два исходных, а оператор `|=` изменяет
# существующий словарь, добавляя элементы из другого.

# Создание двух словарей
user_preferences = {
"theme": "dark",
"notifications": True
}

default_settings = {
"theme": "light",
"language": "en",
"notifications": False
}

# Использование оператора `|` для объединения словарей
combined_settings = default_settings | user_preferences
print("Combined settings (using |):", combined_settings)
# {'theme': 'dark', 'language': 'en', 'notifications': True}

# Использование оператора `|=` для изменения существующего словаря
user_preferences |= {"language": "ru"}
print("Updated user preferences (using |=):", user_preferences)
# {'theme': 'dark', 'notifications': True, 'language': 'ru'}


Подпишись 👉🏻 @KodduuPython 🤖
Для тех кому нужно все и сразу - скикда до 31 января на программу курсов FullStack Developer and Data Scientist (Python+JS+Data) 🔥🔥🔥

Подпишись 👉🏻 @KodduuPython 🤖
Новые возможности для подсказок типов в Python появились с выпуском версии 3.9 и последующих, где добавлены такие полезные функции, как:

1. `Annotated` для аннотации типов метаинформацией.
2. `TypedDict` для описания структур словарей.
3. **Объединение типов с использованием оператора |.
4. `Self` для методов, возвращающих экземпляр своего класса (в Python 3.11+).
5. `Literal` для ограничения значений.

Вот пример, демонстрирующий их использование:


from typing import Annotated, TypedDict, Literal, Self, Union

# 1. Использование Annotated
def process_data(value: Annotated[int, "This should be a positive integer"]) -> int:
if value < 0:
raise ValueError("Value must be positive")
return value * 2

# 2. TypedDict для описания структур словарей
class User(TypedDict):
id: int
name: str
role: Literal["admin", "user", "guest"]

def greet_user(user: User) -> str:
return f"Hello, {user['name']}! Your role is {user['role']}."

# 3. Использование объединения типов (Union или |)
def calculate(value: int | float) -> float:
return value * 1.5

# 4. Использование Self для методов, возвращающих экземпляр класса
class Chainable:
def __init__(self, value: int) -> None:
self.value = value

def increment(self) -> Self:
self.value += 1
return self

def multiply(self, factor: int) -> Self:
self.value *= factor
return self

# 5. Использование Literal для ограничения значений
def set_priority(level: Literal["low", "medium", "high"]) -> str:
return f"Priority set to {level}"

# Демонстрация работы кода
if __name__ == "__main__":
# Annotated
print(process_data(10))

# TypedDict
user_data = User(id=1, name="Alice", role="admin")
print(greet_user(user_data))

# Объединение типов
print(calculate(10))
print(calculate(3.5))

# Chainable с Self
chain = Chainable(5).increment().multiply(10)
print(f"Final value: {chain.value}")

# Literal
print(set_priority("medium"))


### Особенности:
1. `Annotated` позволяет добавлять комментарии к типам, что полезно для документации и проверки.
2. `TypedDict` помогает описывать словари с фиксированной структурой.
3. Использование | вместо Union делает код более лаконичным.
4. `Self` упрощает аннотацию методов, возвращающих экземпляры своего класса.
5. `Literal` ограничивает возможные значения параметров для большей предсказуемости.

Подпишись 👉🏻 @KodduuPython 🤖
Union в аннотациях типов в Python используется для указания, что значение может принадлежать нескольким различным типам. Это полезно для функций, которые могут работать с разными типами данных.

### Основное описание
- `Union[X, Y, Z]` означает, что значение может быть либо типа X, либо типа Y, либо типа Z.
- В Python 3.10+ появился сокращённый синтаксис с использованием оператора |, который выполняет ту же задачу, что и Union.

### Пример:

from typing import Union

def process_value(value: Union[int, float]) -> float:
# Эта функция принимает либо int, либо float
return value * 2.5

print(process_value(10)) # 25.0 (работает с int)
print(process_value(3.14)) # 7.85 (работает с float)


### Подробности работы
1. Гибкость типов: С помощью Union вы указываете, что функция, переменная или класс поддерживают несколько типов.


def print_length(value: Union[str, list]) -> None:
# Функция работает с строками и списками
print(len(value))

print_length("Hello") # 5
print_length([1, 2, 3]) # 3


2. Сокращённый синтаксис (Python 3.10+): Вместо Union можно писать через |:


def add_numbers(x: int | float, y: int | float) -> float:
return x + y
print(add_numbers(10, 20)) # 30
print(add_numbers(10.5, 20)) # 30.5


3. Проверка типов: Union не гарантирует преобразование типов; функция должна самостоятельно проверять, с каким типом она работает.


def process_data(value: Union[int, str]) -> str:
if isinstance(value, int):
return f"Integer processed: {value * 2}"
elif isinstance(value, str):
return f"String processed: {value.upper()}"
else:
raise ValueError("Unsupported type")

print(process_data(42)) # Integer processed: 84
print(process_data("hello")) # String processed: HELLO


4. Когда не использовать `Union`: Если данные должны быть строго одного типа или вы можете явно преобразовать типы (например, через float(value)`), `Union не обязателен.

### Реальный пример
Union часто используют для работы с библиотеками или API, где входные данные могут быть нескольких типов:


from typing import Union

def get_user_input(data: Union[str, int]) -> str:
# Работает как с числом, так и с текстом
return f"User entered: {str(data)}"

print(get_user_input("Hello")) # User entered: Hello
print(get_user_input(123)) # User entered: 123


### Итог
- Union описывает набор типов, с которыми может работать функция или переменная.
- Он помогает сделать код более гибким, сохраняя при этом статическую проверку типов.
- Синтаксис | упрощает запись и делает её более читаемой в современных версиях Python.

Подпишись 👉🏻 @KodduuPython 🤖
👍2
Код демонстрирует возможности Python для работы со строками, такие как removeprefix, removesuffix, casefold, многострочные f-строки, а также функции для удаления пробелов и работы с многострочным текстом.


# Демонстрация новых возможностей для работы со строками (Python 3.9+)

# 1. removeprefix: Удаляет указанный префикс, если он есть
text_with_prefix = "PythonProgramming"
cleaned_text = text_with_prefix.removeprefix("Python")
print(f"After removeprefix('Python'): {cleaned_text}") # 'Programming'

# 2. removesuffix: Удаляет указанный суффикс, если он есть
text_with_suffix = "ProgrammingInPython"
cleaned_text = text_with_suffix.removesuffix("InPython")
print(f"After removesuffix('InPython'): {cleaned_text}") # 'Programming'

# 3. casefold: Улучшенная версия lower() для более надежного сравнения строк
string1 = "Straße"
string2 = "STRASSE"
are_equal = string1.casefold() == string2.casefold()
print(f"Case-insensitive comparison: {are_equal}") # True

# 4. Форматирование строк с f-string
name = "Alice"
age = 30
message = f"Name: {name}, Age: {age}"
print(f"Formatted message: {message}") # 'Name: Alice, Age: 30'

# 5. multi-line f-strings (Python 3.12+)
item = "book"
price = 19.99
description = (
f"Product: {item}\n"
f"Price: ${price:.2f}\n"
f"Available: {True}"
)
print("Multi-line f-string:")
print(description)

# 6. Использование splitlines для работы с многострочным текстом
multi_line_text = "First line\nSecond line\nThird line"
lines = multi_line_text.splitlines()
print(f"Lines: {lines}") # ['First line', 'Second line', 'Third line']

# 7. Удаление пробельных символов (strip, lstrip, rstrip)
text_with_whitespaces = " Hello, Python! "
print(f"Stripped text: '{text_with_whitespaces.strip()}'") # 'Hello, Python!'
print(f"Left-stripped text: '{text_with_whitespaces.lstrip()}'") # 'Hello, Python! '
print(f"Right-stripped text: '{text_with_whitespaces.rstrip()}'") # ' Hello, Python!'


Подпишись 👉🏻 @KodduuPython 🤖
2
👉 Tech.skills, или технические навыки, это основное для инженера в ИТ. Около ~70% кандидатов не проходят именно по tech.skills.

🙂 Soft.skills — это внешний вид автомобиля и салон. 🤖 Tech.skills — это двигатель, коробка и ходовая.

Хорошо, когда есть все это, но без чего авто не поедет совсем?

🚀 Поэтому забейте на все, кроме tech.skills, качайте их в течение года, вот тут я писал подробный план на 2025 год.

🚂 Часто бывает тяжело самому, параллельно с работой, не сойти с пути качки тех.скиллов, тогда идите к нашему партнеру GeekBrains на курс Python. Они вас точно дотянут 👈

Реклама. Информация о рекламодателе по ссылкам в посте.

Подпишись 👉🏻 @KodduuPython 🤖
2
В Python неизменяемые словари можно создавать с помощью класса types.MappingProxyType. Этот класс предоставляет неизменяемую обёртку для обычного словаря, позволяя вам работать с его данными, но предотвращая изменение их напрямую.

### Пример кода


from types import MappingProxyType

# Исходный изменяемый словарь
mutable_dict = {"a": 1, "b": 2, "c": 3}

# Создаём неизменяемую обёртку
immutable_dict = MappingProxyType(mutable_dict)

# Чтение данных из неизменяемого словаря
print(immutable_dict["a"]) # 1
print(immutable_dict) # {'a': 1, 'b': 2, 'c': 3}

# Попытка изменения вызывает ошибку
try:
immutable_dict["a"] = 10 # Ошибка: TypeError
except TypeError as e:
print(f"Error: {e}")

# Исходный словарь всё ещё можно изменять
mutable_dict["a"] = 42
print(immutable_dict["a"]) # 42 — изменения видны в обёртке


### Зачем нужны неизменяемые словари?

1. Безопасность данных:
Неизменяемые словари полезны, когда вы хотите предоставить доступ к данным, но не хотите, чтобы их могли изменить. Например, если вы передаёте настройки или конфигурацию в функцию, вы можете быть уверены, что их содержимое останется неизменным.

2. Согласованность:
Позволяют гарантировать, что данные остаются неизменными, особенно в многопоточных приложениях, где могут возникнуть проблемы из-за одновременного изменения структуры данных.

3. Кэширование и оптимизация:
Использование неизменяемых объектов, таких как неизменяемые словари, позволяет кэшировать результаты и повторно использовать их без риска изменения.

4. Предотвращение ошибок:
Защита от случайного изменения данных делает код более безопасным и удобным для отладки.

### Особенности:
1. Изменение оригинального словаря: Если исходный словарь изменяется, изменения отражаются и в неизменяемой обёртке.
2. Ограничение доступа: Хотя MappingProxyType защищает от изменений, это не делает словарь полностью безопасным от побочных эффектов, если доступ к оригинальному словарю остаётся.

### Дополнение:
Если вам нужен полностью неизменяемый словарь, вы можете использовать библиотеки, такие как immutables:


pip install immutables


Пример использования:


from immutables import Map

immutable_map = Map({"a": 1, "b": 2})
print(immutable_map["a"]) # 1

# Попытка изменения
try:
immutable_map["a"] = 10 # Ошибка
except TypeError as e:
print(f"Error: {e}")


Неизменяемые структуры данных, такие как MappingProxyType или immutables.Map, идеально подходят для ситуаций, где необходима защита данных от изменения.

Подпишись 👉🏻 @KodduuPython 🤖