Это один из пяти принципов SOLID, которые формулируют правила для написания чистого и поддерживаемого кода в объектно-ориентированном программировании. Согласно SRP, класс или модуль должен иметь только одну причину для изменения, что означает, что он должен выполнять только одну задачу или иметь одну ответственность.
Класс должен решать одну конкретную задачу.
Если необходимо внести изменения в код, это должно быть вызвано только одной причиной. Это упрощает поддержку и тестирование кода.
class User:
def __init__(self, name, email):
self.name = name
self.email = email
def save(self):
# Сохранение данных пользователя в базу данных
print(f"Saving user {self.name} to the database.")
def send_welcome_email(self):
# Отправка приветственного сообщения на электронную почту
print(f"Sending welcome email to {self.email}.")
Для соблюдения принципа SRP разделим класс
User на два отдельных класса: один для управления данными пользователя, другой для отправки сообщений электронной почты.class User:
def __init__(self, name, email):
self.name = name
self.email = email
class UserRepository:
def save(self, user):
# Сохранение данных пользователя в базу данных
print(f"Saving user {user.name} to the database.")
class EmailService:
def send_welcome_email(self, user):
# Отправка приветственного сообщения на электронную почту
print(f"Sending welcome email to {user.email}.")
# Использование классов
user = User("Alice", "alice@example.com")
user_repository = UserRepository()
email_service = EmailService()
user_repository.save(user)
email_service.send_welcome_email(user)
Код становится проще для понимания, так как каждый класс выполняет только одну задачу.
Легче писать тесты для классов, которые имеют одну ответственность.
Проще вносить изменения в один аспект системы, не затрагивая другие.
Классы, реализующие одну задачу, могут быть повторно использованы в других частях системы или в других проектах.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥1
Процесс разработки продукта включает в себя несколько ключевых этапов, которые помогают структурировать и упорядочить работу над проектом.
Этот этап включает в себя сбор и анализ требований к будущему продукту. Целью является понимание того, что именно требуется создать и для кого. Включает: Встречи с клиентами и заинтересованными сторонами для обсуждения требований.
Определение функциональных и нефункциональных требований.
Анализ целевого рынка и конкурентов.
Разработка спецификаций и документации.
На этапе проектирования создается архитектура будущего продукта. Это включает:
Разработка высокоуровневой архитектуры системы.
Детальное проектирование отдельных компонентов и модулей.
Создание схем баз данных, диаграмм классов и других архитектурных диаграмм.
Разработка прототипов пользовательского интерфейса.
Этот этап включает в себя непосредственное написание кода и реализацию функциональности согласно разработанным спецификациям и проектам. Включает:
Разработка модулей и компонентов системы.
Интеграция различных частей системы.
Использование систем контроля версий для управления кодом.
Постоянная проверка кода на соответствие стандартам и требованиям.
Тестирование необходимо для обеспечения качества продукта и выявления ошибок до его развертывания. Включает:
Юнит-тестирование отдельных компонентов.
Интеграционное тестирование для проверки взаимодействия компонентов.
Системное тестирование для проверки всей системы в целом.
Приемочное тестирование для проверки соответствия требованиям клиента.
На этапе развертывания продукт готовится к запуску и становится доступным пользователям. Включает:
Настройка серверов и инфраструктуры.
Развертывание приложений в производственной среде.
Проведение окончательных проверок и тестов в реальной среде.
Подготовка и выпуск документации для пользователей и администраторов.
После развертывания продукта начинается этап его поддержки и сопровождения, чтобы обеспечить его бесперебойную работу и внедрение улучшений. Включает:
Мониторинг работы системы и исправление возникающих ошибок.
Выпуск обновлений и патчей для устранения уязвимостей и улучшения функциональности.
Поддержка пользователей и обработка их запросов.
Планирование и внедрение новых функций и улучшений.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
В Django, кастомный менеджер модели — это способ расширения стандартного менеджера модели (класса
Manager), чтобы добавить дополнительные методы для выполнения более сложных запросов к базе данных. Менеджеры используются для работы с наборами запросов (QuerySets) и предоставляют интерфейс для выполнения операций с базой данных.Вынесение часто используемых запросов в методы менеджера позволяет избежать дублирования кода.
Логика сложных запросов инкапсулируется в методы менеджера, делая код моделей и представлений более чистым и удобочитаемым.
Добавление новых методов к менеджеру позволяет выполнять специфичные для приложения операции с данными.
from django.db import models
from django.utils import timezone
class BookManager(models.Manager):
def by_author(self, author_name):
return self.filter(author__name=author_name)
def published_recently(self):
one_month_ago = timezone.now() - timezone.timedelta(days=30)
return self.filter(publication_date__gte=one_month_ago)
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
noscript = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
publication_date = models.DateTimeField()
# Подключение кастомного менеджера
objects = BookManager()
# Получение книг по автору
books_by_author = Book.objects.by_author('John Doe')
for book in books_by_author:
print(book.noscript)
# Получение книг, опубликованных за последний месяц
recent_books = Book.objects.published_recently()
for book in recent_books:
print(book.noscript)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥5
Это класс, который представляет структуру и логику данных приложения. Модели определяют поля и поведение данных, которые будут храниться в базе данных. Django предоставляет множество типов полей и встроенных методов для создания мощных и гибких моделей.
Поле для автоматического увеличения целого числа, которое обычно используется для первичных ключей.
id = models.AutoField(primary_key=True)
Поле для хранения строк с фиксированной максимальной длиной.
name = models.CharField(max_length=100)
Поле для хранения длинных текстов.
denoscription = models.TextField()
Поле для хранения целых чисел.
age = models.IntegerField()
Поле для хранения чисел с плавающей запятой.
price = models.FloatField()
Поле для хранения булевых значений (True/False).
is_active = models.BooleanField(default=True)
Поле для хранения даты и времени.
created_at = models.DateTimeField(auto_now_add=True)
Поле для создания связи "многие к одному" с другой моделью.
author = models.ForeignKey('Author', on_delete=models.CASCADE) Поле для создания связи "многие ко многим" с другой моделью.
categories = models.ManyToManyField('Category') Поле для создания связи "один к одному" с другой моделью.
profile = models.OneToOneField('Profile', on_delete=models.CASCADE) Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Это два важных понятия в контексте работы интернета и компьютерных сетей. Они используются для идентификации устройств и ресурсов в сети, а также для упрощения доступа к ним.
Это уникальный числовой идентификатор, присваиваемый каждому устройству, подключенному к сети, использующей протокол IP (Internet Protocol). IP-адреса используются для маршрутизации пакетов данных между устройствами в сети.
Формат: 32-битные числа, записанные в виде четырех десятичных чисел, разделенных точками (например, 192.168.1.1). Пример: 192.168.0.1, 8.8.8.8
Формат: 128-битные числа, записанные в виде восьми групп шестнадцатеричных чисел, разделенных двоеточиями (например, 2001:0db8:85a3:0000:0000:8a2e:0370:7334). Пример: 2001:0db8:85a3:0000:0000:8a2e:0370:7334, ::1 (loopback адрес)
Это удобочитаемое имя, используемое для идентификации IP-адреса на уровне пользователя. Доменные имена упрощают доступ к ресурсам в интернете, так как их легче запомнить и использовать, чем числовые IP-адреса.
Верхний уровень, например, .com, .org, .net.
Основная часть доменного имени, например, example в example.com.
Дополнительные уровни, например, www в www.example.com.
Для преобразования доменных имен в IP-адреса используется система доменных имен (DNS, Domain Name System). DNS-серверы выполняют роль "телефонной книги" интернета, переводя доменные имена в соответствующие им IP-адреса.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥1
Это способность программы исследовать и изменять свою структуру и поведение во время выполнения. Интроспекция позволяет получить информацию о типах данных, структурах, объектах и их атрибутах динамически, то есть в процессе выполнения программы.
С помощью функции
type() можно узнать тип любого объекта. x = 10
print(type(x)) # <class 'int'>
Функции
hasattr(), getattr() и setattr() позволяют проверять и манипулировать атрибутами объектов. class MyClass:
def __init__(self, value):
self.value = value
obj = MyClass(5)
# Проверка наличия атрибута
print(hasattr(obj, 'value')) # True
# Получение значения атрибута
print(getattr(obj, 'value')) # 5
# Установка значения атрибута
setattr(obj, 'value', 10)
print(getattr(obj, 'value')) # 10
Модуль
inspect предоставляет функции для получения информации о классах, методах и функциях. import inspect
class MyClass:
def method(self):
pass
# Получение всех методов класса
methods = inspect.getmembers(MyClass, predicate=inspect.isfunction)
print(methods) # [('method', <function MyClass.method at 0x...>)]
Встроенная функция
dir() возвращает список всех атрибутов и методов объекта. class MyClass:
def method(self):
pass
obj = MyClass()
print(dir(obj))
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
# '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
# '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'method']
Модуль
inspect предоставляет функции для получения информации о живых объектах, включая функции, методы, классы и модули. import inspect
def my_function():
pass
# Получение информации о функции
print(inspect.getmembers(my_function))
Позволяет писать более общие и гибкие функции, которые могут работать с различными типами данных.
Облегчает отладку и тестирование кода, предоставляя средства для анализа объектов и их состояния.
Может сделать код более сложным для понимания и сопровождения.
Интроспекция может повлиять на производительность, особенно при частом использовании в критически важных участках кода.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤1
•Например: O(1) (константное время), O(n) (линейное), O(log n) (логарифмическое).
Она помогает сравнивать алгоритмы и выбирать наиболее оптимальный для конкретной задачи.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥2
Это легковесный формат обмена данными, который легко читается и пишется человеком, а также легко парсится и генерируется машинами. JSON используется для передачи данных между клиентом и сервером, особенно в веб-приложениях.
JSON простой и легкий для понимания, что делает его удобным для обмена данными.
JSON представлен в текстовом формате, что позволяет легко его читать и отлаживать.
Хотя JSON основан на подмножестве языка JavaScript, он поддерживается многими языками программирования, включая Python, Java, C#, PHP и другие.
Набор пар "ключ-значение", заключенный в фигурные скобки
{}. Ключи должны быть строками, а значения могут быть различными типами данных.Упорядоченные списки значений, заключенные в квадратные скобки
[].{
"name": "John Doe",
"age": 30,
"isStudent": false,
"courses": ["Math", "Science", "History"],
"address": {
"street": "123 Main St",
"city": "Anytown",
"zip": "12345"
}
}Последовательности символов, заключенные в двойные кавычки.
"name": "John Doe"
Целые числа и числа с плавающей запятой.
"age": 30
true или false. "isStudent": false
Упорядоченные списки значений.
"courses": ["Math", "Science", "History"]
Наборы пар "ключ-значение".
"address": {
"street": "123 Main St",
"city": "Anytown",
"zip": "12345"
} Значение null.
"middleName": null
Преобразование Python объектов в JSON (сериализация)
import json
data = {
"name": "John Doe",
"age": 30,
"isStudent": False,
"courses": ["Math", "Science", "History"],
"address": {
"street": "123 Main St",
"city": "Anytown",
"zip": "12345"
}
}
# Преобразование Python объекта в JSON строку
json_string = json.dumps(data, indent=4)
print(json_string)
Преобразование JSON в Python объекты (десериализация)
import json
json_string = '''
{
"name": "John Doe",
"age": 30,
"isStudent": false,
"courses": ["Math", "Science", "History"],
"address": {
"street": "123 Main St",
"city": "Anytown",
"zip": "12345"
}
}
'''
# Преобразование JSON строки в Python объект
data = json.loads(json_string)
print(data)
print(data['name']) # John Doe
Запись JSON в файл
import json
data = {
"name": "John Doe",
"age": 30,
"isStudent": False,
"courses": ["Math", "Science", "History"],
"address": {
"street": "123 Main St",
"city": "Anytown",
"zip": "12345"
}
}
with open('data.json', 'w') as file:
json.dump(data, file, indent=4)
Чтение JSON из файла
import json
with open('data.json', 'r') as file:
data = json.load(file)
print(data)
print(data['name']) # John Doe
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤5
2. rebase: перемещает изменения текущей ветки поверх другой, переписывая историю. Это делает историю линейной и более чистой, но может привести к конфликтам и проблемам при совместной работе.
merge используется для сохранения полной истории, а rebase — для её упрощения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍4💊2
IntegerChoices в Django используется для создания выбора из ограниченного набора целочисленных значений для поля модели. Это полезно, когда вам нужно ограничить допустимые значения для поля модели определенными целыми числами, и при этом иметь удобные человекочитаемые названия для этих значений.Значения выбора имеют человекочитаемые названия, что делает код более понятным.
Django автоматически проверяет, что значение поля соответствует одному из допустимых значений.
В Django admin интерфейсе выпадающий список с человекочитаемыми названиями делает работу с данными удобнее.
IntegerChoicesfrom django.db import models
class Status(models.IntegerChoices):
PENDING = 1, 'Pending'
APPROVED = 2, 'Approved'
REJECTED = 3, 'Rejected'
IntegerChoices в моделиfrom django.db import models
class Application(models.Model):
status = models.IntegerField(choices=Status.choices, default=Status.PENDING)
name = models.CharField(max_length=100)
submitted_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.name} - {self.get_status_display()}"
# Создание новой записи
app = Application.objects.create(name='John Doe')
# Проверка статуса
print(app.status) # 1
print(app.get_status_display()) # 'Pending'
# Изменение статуса
app.status = Status.APPROVED
app.save()
# Проверка обновленного статуса
print(app.status) # 2
print(app.get_status_display()) # 'Approved'
Вы можете добавлять дополнительные методы и атрибуты в класс выбора для расширенной функциональности.
from django.db import models
class Status(models.IntegerChoices):
PENDING = 1, 'Pending'
APPROVED = 2, 'Approved'
REJECTED = 3, 'Rejected'
@classmethod
def get_choices(cls):
return [(choice.value, choice.label) for choice in cls]
# Пример использования
print(Status.get_choices()) # [(1, 'Pending'), (2, 'Approved'), (3, 'Rejected')]
Использование в фильтрах и запросах
# Фильтрация записей по статусу
pending_apps = Application.objects.filter(status=Status.PENDING)
for app in pending_apps:
print(app.name)
# Фильтрация записей по множеству статусов
approved_or_rejected_apps = Application.objects.filter(status__in=[Status.APPROVED, Status.REJECTED])
for app in approved_or_rejected_apps:
print(app.name)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1💊1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍4
В Django существует несколько вариантов определения модели пользователя. По умолчанию Django предоставляет базовую модель пользователя, но если требуется кастомизация, можно создать свою модель пользователя.
Django предоставляет стандартную модель пользователя через
django.contrib.auth.models.User. Эта модель включает в себя все основные поля и методы для работы с пользователями.from django.contrib.auth.models import User
# Создание нового пользователя
user = User.objects.create_user(username='john', password='password123')
# Аутентификация пользователя
from django.contrib.auth import authenticate, login
user = authenticate(username='john', password='password123')
if user is not None:
login(request, user)
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(blank=True)
birth_date = models.DateField(null=True, blank=True)
# Сигналы для автоматического создания и сохранения профиля пользователя
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.userprofile.save()
# Получение и изменение профиля пользователя
user = User.objects.get(username='john')
profile = user.userprofile
profile.bio = "Hello, I'm John!"
profile.save()
Если необходимо полностью изменить модель пользователя, можно создать кастомную модель пользователя и указать Django использовать её вместо стандартной.
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models
class CustomUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('The Email field must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
return self.create_user(email, password, **extra_fields)
class CustomUser(AbstractBaseUser):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = CustomUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']
def __str__(self):
return self.email
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1
QuerySet в Django является ленивым, что означает, что запросы к базе данных выполняются только при необходимости (например, при итерации или вызове методов вроде .all() или .filter()). Это позволяет оптимизировать работу с данными и предотвращать лишние запросы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥6
Это механизм, который позволяет программам обмениваться данными по сети. Они являются одним из основных способов коммуникации между устройствами в сетях, таких как интернет или локальная сеть (LAN). Сокеты используются для реализации различных сетевых протоколов, таких как TCP (Transmission Control Protocol) и UDP (User Datagram Protocol).
Сокеты используются для связи между двумя устройствами по сети, такие как клиент и сервер.
TCP-сокеты (стриминговые сокеты): Обеспечивают надежное, установочное соединение с проверкой целостности данных и управлением потоком. Пример использования — веб-серверы и клиенты.
UDP-сокеты (датаграммные сокеты): Обеспечивают безустановочное соединение с меньшей задержкой, но без гарантии доставки данных. Пример использования — видеостриминг, игры в реальном времени.
TCP-сокеты
Сервер
import socket
# Создание TCP-сокета
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Привязка сокета к адресу и порту
server_socket.bind(('localhost', 12345))
# Ожидание входящих соединений
server_socket.listen()
print('Сервер ожидает соединения...')
while True:
# Принятие нового соединения
client_socket, client_address = server_socket.accept()
print(f'Подключение от {client_address}')
# Получение данных от клиента
data = client_socket.recv(1024).decode()
print(f'Получено: {data}')
# Отправка ответа клиенту
client_socket.sendall('Hello, Client!'.encode())
# Закрытие соединения
client_socket.close()
Клиент
import socket
# Создание TCP-сокета
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Подключение к серверу
client_socket.connect(('localhost', 12345))
# Отправка данных серверу
client_socket.sendall('Hello, Server!'.encode())
# Получение ответа от сервера
data = client_socket.recv(1024).decode()
print(f'Получено: {data}')
# Закрытие соединения
client_socket.close()
UDP-сокеты
Сервер
import socket
# Создание UDP-сокета
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Привязка сокета к адресу и порту
server_socket.bind(('localhost', 12345))
print('UDP сервер ожидает сообщений...')
while True:
# Получение данных от клиента
data, client_address = server_socket.recvfrom(1024)
print(f'Получено от {client_address}: {data.decode()}')
# Отправка ответа клиенту
server_socket.sendto('Hello, Client!'.encode(), client_address)
Клиент
import socket
# Создание UDP-сокета
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Отправка данных серверу
client_socket.sendto('Hello, Server!'.encode(), ('localhost', 12345))
# Получение ответа от сервера
data, server_address = client_socket.recvfrom(1024)
print(f'Получено: {data.decode()}')
# Закрытие сокета
client_socket.close()
Сокеты предоставляют низкоуровневый доступ к сетевым операциям, позволяя разрабатывать различные сетевые протоколы.
Обеспечивают надежную передачу данных с управлением потоком и проверкой целостности.
Позволяют быстро передавать данные с минимальной задержкой.
Работа с сокетами требует понимания сетевых протоколов и управления соединениями.
Данные могут теряться или приходить в неправильном порядке.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥2
Метод
__call__ является специальным методом, который позволяет экземплярам классов вести себя как функции. Если объект класса имеет данный метод, то этот объект можно вызывать, как если бы он был функцией. Это может быть полезно для создания объектов, которые действуют как замыкания, для реализации паттернов проектирования и других сценариев, требующих функциональности.Позволяет объекту вести себя как функция. Он вызывается, когда экземпляр класса вызывается как функция.
class Counter:
def __init__(self):
self.count = 0
def __call__(self):
self.count += 1
return self.count
# Использование
counter = Counter()
print(counter()) # Вывод: 1
print(counter()) # Вывод: 2
print(counter()) # Вывод: 3
Позволяет создавать объекты, которые можно вызывать как функции, что полезно для создания замыканий и функций высшего порядка.
Используется для реализации механизмов кеширования в классах, когда результат вычисления может быть закеширован и повторно использован.
class Multiplier:
def __init__(self, factor):
self.factor = factor
def __call__(self, value):
return value * self.factor
# Использование
double = Multiplier(2)
triple = Multiplier(3)
print(double(5)) # Вывод: 10
print(triple(5)) # Вывод: 15
Пример кеширования
class CachedFibonacci:
def __init__(self):
self.cache = {}
def __call__(self, n):
if n in self.cache:
return self.cache[n]
if n <= 1:
return n
self.cache[n] = self(n - 1) + self(n - 2)
return self.cache[n]
# Использование
fibonacci = CachedFibonacci()
print(fibonacci(10)) # Вывод: 55
print(fibonacci(15)) # Вывод: 610
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤4💊1
Это структура данных, которая хранит пары ключ-значение и использует хеш-функцию для вычисления индекса.
Хеширование: ключ преобразуется в числовое значение (хеш).
Размещение: хеш определяет индекс, куда сохраняется значение.
Коллизии: если два ключа имеют одинаковый хеш, используется метод разрешения коллизий (связанный список, открытая адресация).
Хеш-таблицы обеспечивают быстрый доступ (O(1)) к данным при правильной реализации.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤1