- GROUP BY агрегирует строки — возвращается одна строка на группу.
- Оконная функция не агрегирует строки, а добавляет результат в каждую строку, сохраняя весь набор данных. Это даёт больше гибкости при аналитике.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2💊1
Middleware (промежуточное ПО) — это специальные классы, которые обрабатывают запросы и ответы, проходящие через Django. Они позволяют изменять данные, проверять доступ, логировать действия и многое другое.
Добавляет важные HTTP-заголовки для защиты сайта:
-
Strict-Transport-Security (HTTPS) -
X-Content-Type-Options: nosniff -
X-Frame-Options: DENY Отвечает за:
Перенаправление с
APPEND_SLASH=True (если /about → перенаправит на /about/). Удаление
www. (www.example.com → example.com). Обработка кодировки и контента.
Позволяет Django хранить данные пользователя между запросами (например, авторизацию).
request.session["user_id"] = 42 # Сохраняем ID пользователя в сессии
Позволяет работать с
request.user, автоматически определяя пользователя. if request.user.is_authenticated:
print(f"Пользователь: {request.user.username}")
Защищает от атак межсайтовой подделки запросов (CSRF).
При обработке форм Django требует специальный CSRF-токен:
<form method="POST">
{% csrf_token %}
<input type="text" name="name">
</form>
Запрещает встраивать сайт в
<iframe>, предотвращая атаку Clickjacking. X-Frame-Options: DENY
Позволяет передавать временные сообщения (
django.contrib.messages). from django.contrib import messages
messages.success(request, "Вы успешно вошли!")
messages.error(request, "Ошибка авторизации!")
Мидлвари хранятся в
settings.py: MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
]
Допустим, хотим логировать все запросы.
Создаём
middleware.py import datetime
class LogMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
print(f"[{datetime.datetime.now()}] Запрос: {request.path}")
response = self.get_response(request)
return response
Добавляем в
settings.py MIDDLEWARE.append("myapp.middleware.LogMiddleware")Теперь в консоли будем видеть все запросы!
[2024-02-28 12:00:00] Запрос: /
[2024-02-28 12:01:00] Запрос: /login/
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
- Чтобы собрать связанную информацию из нескольких таблиц;
- Для реализации нормализованных структур;
- Упрощают анализ и отчёты, объединяя бизнес-данные;
- Позволяют избегать избыточности за счёт связей.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Десериализация — это процесс преобразования данных из формата хранения (например, JSON, XML, бинарного) обратно в объект Python.
Клиент получает JSON-ответ от сервера и преобразует его в объекты.
Загружаем настройки программы из файла.
Данные хранятся в виде строк и извлекаются как объекты.
JSON (JavaScript Object Notation) — популярный формат хранения и передачи данных.
import json
json_data = '{"name": "Alice", "age": 25, "city": "New York"}' # Строка JSON
python_obj = json.loads(json_data) # Десериализуем в словарь
print(python_obj) # {'name': 'Alice', 'age': 25, 'city': 'New York'}
print(python_obj["name"]) # Alice
Pickle используется для хранения объектов Python в файлах или передаче их по сети.
import pickle
binary_data = b'\x80\x04\x95\x11\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x05Alice\x94u.'
python_obj = pickle.loads(binary_data) # Десериализуем
print(python_obj) # {'name': 'Alice'}
Если данные хранятся в файле, их можно загрузить обратно в программу.
with open("data.json", "r") as file:
python_obj = json.load(file) # Загружаем JSON из файла
print(python_obj)Pickle может содержать вредоносный код, так что никогда не десериализуйте неизвестные данные!
import pickle
pickle.loads(b"cos\nsystem\n(S'rm -rf /'\ntR.") # Опасная команда
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
dict и list — разные по структуре и назначению типы:
- list — упорядоченный набор элементов. Элементы хранятся по индексу. Подходит для последовательного хранения и перебора.
- dict — ассоциативный массив, где данные хранятся как пары ключ: значение. Позволяет быстро искать значения по ключу.
Списки полезны, когда важен порядок и позиция, словари — когда важна ассоциативность и быстрый доступ по ключу.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Моржовый оператор (
:=) – это новый оператор, появившийся в Python 3.8, который позволяет присваивать значение переменной прямо внутри выражения. Обычно мы записываем код так:
value = len(my_list) # Сначала присваиваем
if value > 10: # Потом используем
print("Список большой")
С
:= можно совместить оба действия if (value := len(my_list)) > 10:
print("Список большой")
В циклах (избегаем лишних вычислений). Вместо:
data = input("Введите строку: ")
while data != "exit":
print("Вы ввели:", data)
data = input("Введите строку: ")С
:= можно записать короче:while (data := input("Введите строку: ")) != "exit":
print("Вы ввели:", data)В
if и while (проверяем и присваиваем одновременно) Без
:=text = input("Введите слово: ")
if len(text) > 5:
print(f"Слово длинное ({len(text)} символов)")С
:=:if (length := len(text)) > 5:
print(f"Слово длинное ({length} символов)")
В списковых включениях (list comprehensions)
Без
:=:numbers = [random.randint(1, 100) for _ in range(10)]
filtered = [num for num in numbers if num % 2 == 0]
С
:=:filtered = [num for _ in range(10) if (num := random.randint(1, 100)) % 2 == 0]
Если код становится сложнее для чтения
if (a := func()) and (b := another_func(a)) > 10:
...
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🤔2
Потому что:
- Данные передаются в URL, и могут попасть в историю браузера, логи, прокси.
- Это небезопасно, особенно для логинов, паролей и токенов.
- GET предназначен для чтения, а не отправки чувствительных данных.
POST — безопаснее, так как данные передаются в теле запроса, а не в адресной строке.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍2
В Python можно создать класс двумя основными способами:
Через
class (обычный способ) Через
type() (динамическое создание класса) Это стандартный способ, который мы используем чаще всего.
class Person:
def __init__(self, name):
self.name = name
def say_hello(self):
return f"Привет, я {self.name}!"
p = Person("Алиса")
print(p.say_hello()) # Привет, я Алиса!
Функция
type() позволяет создать класс "на лету". Person = type("Person", (object,), {
"__init__": lambda self, name: setattr(self, "name", name),
"say_hello": lambda self: f"Привет, я {self.name}!"
})
p = Person("Боб")
print(p.say_hello()) # Привет, я Боб!Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7💊2🔥1
TCP/IP — это набор сетевых протоколов, на которых работает интернет.
Он определяет, как компьютеры обмениваются данными в сети: как разбиваются, передаются, маршрутизируются и собираются пакеты.
TCP/IP — это основа передачи данных в интернете и локальных сетях.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6💊2
Модуль
datetime позволяет работать с датами и временем, но по умолчанию он не поддерживает часовые пояса.from datetime import datetime
dt = datetime.now() # Получаем текущую дату и время
print(dt) # Например: 2024-02-28 14:30:00.123456
print(dt.tzinfo) # None (нет информации о часовом поясе)
Библиотека
pytz добавляет поддержку часовых поясов и позволяет работать с разными временными зонами. from datetime import datetime
import pytz
tz = pytz.timezone("Europe/Moscow") # Часовой пояс Москвы
dt = datetime.now(tz) # Получаем текущее время с учетом часового пояса
print(dt) # Например: 2024-02-28 17:30:00+03:00
print(dt.tzinfo) # Europe/Moscow
Создание
datetime с часовым поясом pytz dt = datetime(2024, 2, 28, 15, 0) # Наивная дата
tz = pytz.timezone("Europe/Moscow")
dt = tz.localize(dt) # Присваиваем часовой пояс
print(dt) # 2024-02-28 15:00:00+03:00
Конвертация времени между часовыми поясами
ny_tz = pytz.timezone("America/New_York")
ny_time = dt.astimezone(ny_tz)
print(ny_time) # Конвертированное время в Нью-ЙоркеИспользование UTC (лучший подход для серверов)
utc_now = datetime.now(pytz.UTC) # Текущее время в UTC
print(utc_now) # Например: 2024-02-28 14:30:00+00:00
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2
Media is too big
VIEW IN TELEGRAM
На программиста, тестировщика, аналитика, проджекта и другие IT профы.
Есть собесы от ведущих компаний: Сбер, Яндекс, ВТБ, Тинькофф, Озон, Wildberries и т.д.
🎯 Переходи по ссылке и присоединяйся к базе, чтобы прокачать свои шансы на успешное трудоустройство!
Please open Telegram to view this post
VIEW IN TELEGRAM
Нет, генераторы не поддерживают индексацию. Их элементы можно получить только путём итерации.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Это поведенческий паттерн проектирования, который определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Паттерн "Стратегия" позволяет изменять алгоритмы независимо от клиентов, которые их используют.
Позволяет инкапсулировать различные алгоритмы и использовать их независимо.
Устраняет дублирование кода и упрощает классы, которые используют эти алгоритмы.
Легко добавлять новые алгоритмы или изменять существующие без изменения клиентского кода.
Интерфейс, определяющий общий метод, который должны реализовать все алгоритмы.
Реализации различных алгоритмов, которые реализуют интерфейс стратегии.
Класс, использующий стратегию для выполнения задачи.
from abc import ABC, abstractmethod
# Интерфейс стратегии
class Strategy(ABC):
@abstractmethod
def sort(self, data):
pass
# Конкретные стратегии
class BubbleSortStrategy(Strategy):
def sort(self, data):
print("Sorting using Bubble Sort")
for i in range(len(data)):
for j in range(0, len(data)-i-1):
if data[j] > data[j+1]:
data[j], data[j+1] = data[j+1], data[j]
class QuickSortStrategy(Strategy):
def sort(self, data):
print("Sorting using Quick Sort")
self.quick_sort(data, 0, len(data) - 1)
def quick_sort(self, data, low, high):
if low < high:
pi = self.partition(data, low, high)
self.quick_sort(data, low, pi - 1)
self.quick_sort(data, pi + 1, high)
def partition(self, data, low, high):
pivot = data[high]
i = low - 1
for j in range(low, high):
if data[j] <= pivot:
i = i + 1
data[i], data[j] = data[j], data[i]
data[i + 1], data[high] = data[high], data[i + 1]
return i + 1
# Контекст
class SortingContext:
def __init__(self, strategy: Strategy):
self._strategy = strategy
def set_strategy(self, strategy: Strategy):
self._strategy = strategy
def sort(self, data):
self._strategy.sort(data)
# Клиентский код
data = [5, 2, 9, 1, 5, 6]
context = SortingContext(BubbleSortStrategy())
context.sort(data)
print(data) # [1, 2, 5, 5, 6, 9]
context.set_strategy(QuickSortStrategy())
data = [3, 7, 8, 5, 2, 1, 9, 5, 4]
context.sort(data)
print(data) # [1, 2, 3, 4, 5, 5, 7, 8, 9]
Алгоритмы инкапсулируются в отдельные классы, что упрощает их замену и добавление.
Контекст использует стратегии, избегая громоздких условных операторов.
Легко добавлять новые стратегии без изменения существующего кода.
Добавление множества классов стратегий может усложнить проект.
Контекст должен знать о всех возможных стратегиях, чтобы иметь возможность их переключать.
Когда есть несколько вариантов алгоритмов для выполнения задачи.
Когда нужно динамически выбирать алгоритм во время выполнения.
Когда необходимо избежать множества условных операторов для выбора алгоритма.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Old-style классы были в Python 2 и не наследовали object. В Python 3 все классы автоматически new-style и обладают расширенными возможностями
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔4👍1
Это методология управления процессом создания программного обеспечения, которая включает в себя последовательность этапов и действий, необходимых для разработки, тестирования, развертывания и поддержки программных продуктов. Цель SDLC — обеспечить структурированный и эффективный подход к разработке ПО, минимизируя риски и повышая качество конечного продукта.
На этом этапе определяются цели проекта, анализируются потребности и требования к системе. Включает сбор требований от заинтересованных сторон, анализ бизнес-процессов и создание документации с описанием требований.
Встречи с клиентами и пользователями для определения функций системы. Документирование функциональных и нефункциональных требований.
На этапе проектирования разрабатывается архитектура системы и ее компоненты. Создаются технические спецификации, включая схемы базы данных, диаграммы классов и интерфейсов, а также детализируется план реализации.Разработка диаграмм UML.Создание прототипов пользовательского интерфейса.Проектирование архитектуры системы.
На этом этапе осуществляется непосредственная разработка программного обеспечения на основе спецификаций, созданных на предыдущем этапе. Кодирование выполняется в соответствии с выбранными языками программирования и инструментами разработки. Написание кода для модулей и компонентов системы. Интеграция различных компонентов системы. Регулярное использование систем контроля версий (например, Git).
Этап тестирования включает проверку и валидацию системы для обнаружения и исправления ошибок. Тестирование проводится в различных формах, включая юнит-тестирование, интеграционное тестирование, системное тестирование и приемочное тестирование. Автоматизированное тестирование с использованием фреймворков, таких как pytest или JUnit. Ручное тестирование функциональности и пользовательского интерфейса. Тестирование производительности и безопасности.
На этом этапе программное обеспечение разворачивается в рабочей среде и становится доступным пользователям. Включает настройку серверов, развертывание баз данных и настройку инфраструктуры. Развертывание на облачных платформах, таких как AWS или Azure. Настройка и конфигурация серверов и сетей. Миграция данных и начальная загрузка данных.
Этап поддержки и сопровождения включает в себя обслуживание и улучшение системы после ее развертывания. Включает исправление ошибок, обновление функциональности и оптимизацию производительности. Обновление системы безопасности. Внесение изменений на основе отзывов пользователей. Обслуживание серверов и баз данных.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Хеш-таблица (HashMap) — это структура данных, которая позволяет быстро хранить и искать пары ключ → значение. В Python её аналогом является
dict.Ключ проходит через хеш-функцию → превращается в число (индекс).
Значение сохраняется в массиве по этому индексу.
При поиске: ключ снова хешируется, и мы мгновенно находим нужное значение.
Создание хеш-таблицы (
dict)hash_map = {} # Пустой словарь
hash_map["apple"] = 10 # Добавляем элемент
hash_map["banana"] = 20
print(hash_map["apple"]) # 10Ключи сначала хешируются с помощью встроенной функции
hash(). print(hash("apple")) # Например: 2837462816
print(hash("banana")) # Другое числоИногда разные ключи могут давать одинаковый хеш. Это называется коллизией. Python использует метод цепочек (Chaining): Если у двух ключей один хеш, они хранятся в виде списка в одной ячейке.
hash_map = { "key1": 100, "key2": 200 }
print(hash("key1") % 10) # Допустим, 4
print(hash("key2") % 10) # Тоже 4 (коллизия!)
# Python хранит их в одной ячейке как список [(key1, 100), (key2, 200)]При заполнении хеш-таблицы, если она становится слишком загруженной, Python автоматически увеличивает её размер, чтобы избежать замедления.
d = {} # Создаём пустой dict
for i in range(1000):
d[i] = i
print(len(d)) # 1000, Python сам расширил таблицуУдаление также выполняется за O(1)
del hash_map["apple"] # Мгновенно удаляем
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
- URI — это общее понятие: любой способ идентификации ресурса.
- URL — это конкретный тип URI, указывающий, где найти ресурс и как его получить.
То есть все URL — это URI, но не все URI — это URL.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4💊4
Многопоточность в Python реализуется с помощью модуля
threading, но из-за GIL (Global Interpreter Lock) потоки не могут выполняться параллельно на нескольких ядрах. Модуль
threading позволяет запускать несколько потоков (threads) в одном процессе. import threading
import time
def task(name):
print(f"{name} начал работу")
time.sleep(2) # Имитация задержки
print(f"{name} завершил работу")
# Создаём два потока
t1 = threading.Thread(target=task, args=("Поток 1",))
t2 = threading.Thread(target=task, args=("Поток 2",))
t1.start()
t2.start()
t1.join()
t2.join()
print("Все потоки завершены")
Вывод
Поток 1 начал работу
Поток 2 начал работу
(пауза 2 секунды)
Поток 1 завершил работу
Поток 2 завершил работу
Все потоки завершены
В отличие от
threading, модуль multiprocessing создаёт отдельные процессы, которые могут выполняться на разных ядрах процессора. import multiprocessing
import time
def task(name):
print(f"{name} начал работу")
time.sleep(2)
print(f"{name} завершил работу")
if __name__ == "__main__":
p1 = multiprocessing.Process(target=task, args=("Процесс 1",))
p2 = multiprocessing.Process(target=task, args=("Процесс 2",))
p1.start()
p2.start()
p1.join()
p2.join()
print("Все процессы завершены")
Этот модуль позволяет легко управлять потоками (
ThreadPoolExecutor) и процессами (ProcessPoolExecutor). from concurrent.futures import ThreadPoolExecutor
import time
def task(n):
time.sleep(2)
return f"Готово: {n}"
with ThreadPoolExecutor(max_workers=2) as executor:
results = executor.map(task, [1, 2, 3])
for result in results:
print(result)
Пример
ProcessPoolExecutor (процессы)from concurrent.futures import ProcessPoolExecutor
def square(n):
return n * n
with ProcessPoolExecutor() as executor:
results = executor.map(square, [1, 2, 3, 4])
print(list(results)) # [1, 4, 9, 16]
Модуль
asyncio не создаёт потоки или процессы, а работает через "корутины" и цикл событий (event loop). import asyncio
async def task():
print("Начало")
await asyncio.sleep(2) # Не блокирует другие задачи
print("Конец")
async def main():
await asyncio.gather(task(), task())
asyncio.run(main())
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Оригинальный объект будет заменён на None, что приведёт к ошибке при попытке вызова. Это типичная ошибка при написании декоратора без return.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5