В SQL можно объединять данные из двух таблиц без использования
JOIN
, используя альтернативные методы. Подзапрос (
subquery
) позволяет выбрать данные из одной таблицы, используя данные из другой. Допустим, у нас есть две таблицы:
employees (id, name, department_id)
departments (id, name)
SELECT name,
(SELECT name FROM departments WHERE id = employees.department_id) AS department_name
FROM employees;
Можно фильтровать данные из одной таблицы, проверяя наличие значений в другой.
SELECT name
FROM employees
WHERE department_id IN (SELECT id FROM departments);
Если таблицы имеют схожие колонки, можно объединить их с
UNION
. SELECT id, name, email FROM users_old
UNION
SELECT id, name, email FROM users_new;
Хотя
CROSS JOIN
делает декартово произведение, его можно фильтровать WHERE
, имитируя INNER JOIN
. SELECT e.name, d.name AS department
FROM employees e, departments d
WHERE e.department_id = d.id;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥2
Для сортировки списка словарей по определенному полю в Python удобно использовать функцию sorted() или метод sort(). Оба подхода позволяют указать ключ сортировки с помощью параметра key, где можно передать либо функцию, либо лямбда-выражение, которое извлекает значение из словаря для сортировки.
Списки словарей часто используются для хранения структурированных данных. Например, вы можете иметь список сотрудников, где каждый сотрудник представлен в виде словаря с полями, такими как имя, возраст и зарплата. Сортировка по определенному полю позволяет упорядочить данные, чтобы ими было проще пользоваться или отображать.
Эта функция возвращает новый отсортированный список.
employees = [
{"name": "Alice", "age": 30, "salary": 70000},
{"name": "Bob", "age": 25, "salary": 50000},
{"name": "Charlie", "age": 35, "salary": 120000}
]
# Сортировка по возрасту
sorted_employees = sorted(employees, key=lambda x: x["age"])
print(sorted_employees)
Результат
[{'name': 'Bob', 'age': 25, 'salary': 50000},
{'name': 'Alice', 'age': 30, 'salary': 70000},
{'name': 'Charlie', 'age': 35, 'salary': 120000}]
Этот метод изменяет существующий список.
employees = [
{"name": "Alice", "age": 30, "salary": 70000},
{"name": "Bob", "age": 25, "salary": 50000},
{"name": "Charlie", "age": 35, "salary": 120000}
]
# Сортировка по зарплате
employees.sort(key=lambda x: x["salary"])
print(employees)
Результат
[{'name': 'Bob', 'age': 25, 'salary': 50000},
{'name': 'Alice', 'age': 30, 'salary': 70000},
{'name': 'Charlie', 'age': 35, 'salary': 120000}]
Установите параметр reverse=True, чтобы отсортировать в порядке убывания.
sorted_employees_desc = sorted(employees, key=lambda x: x["age"], reverse=True)
print(sorted_employees_desc)
Это более эффективный способ, чем лямбда-функция, особенно для больших данных.
from operator import itemgetter
sorted_employees = sorted(employees, key=itemgetter("age"))
print(sorted_employees)
Если поле может отсутствовать в некоторых словарях, можно использовать параметр key для обработки таких ситуаций.
employees = [
{"name": "Alice", "age": 30},
{"name": "Bob"},
{"name": "Charlie", "age": 35}
]
sorted_employees = sorted(employees, key=lambda x: x.get("age", 0))
print(sorted_employees)
Результат
[{'name': 'Bob'},
{'name': 'Alice', 'age': 30},
{'name': 'Charlie', 'age': 35}]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥3
Доменное имя — это человеко-понятный адрес сайта в интернете, например:
Оно состоит из уровней:
- com — домен верхнего уровня.
- example — домен второго уровня.
- Можно также иметь поддомены:
Домен привязан к IP-адресу через DNS.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥2
Это небольшой файл, который создаётся веб-сайтом и сохраняется в браузере пользователя. Куки используются для хранения информации, связанной с пользователем, чтобы улучшить его взаимодействие с сайтом.
Куки помогают веб-сайтам «запоминать» данные о пользователе. Вот основные цели их использования:
Например, после входа в аккаунт куки сохраняют ваш статус (авторизован вы или нет).
Куки могут хранить ваши настройки, например, выбранный язык или тему сайта.
Если вы добавляете товары в корзину в интернет-магазине, эта информация может храниться в куки.
Куки используются для аналитики и рекламы, чтобы понять, как вы взаимодействуете с сайтом, или показать персонализированные объявления.
Когда вы заходите на сайт, сервер может отправить куки вашему браузеру вместе с HTTP-ответом.
Браузер сохраняет эти данные и отправляет их обратно на сервер при последующих запросах.
Куки привязаны к домену, и только этот домен может их читать.
Создание куки на сервере (Python, Flask)
from flask import Flask, request, make_response
app = Flask(__name__)
@app.route('/set_cookie')
def set_cookie():
response = make_response("Cookie установлена!")
response.set_cookie('username', 'JohnDoe') # Устанавливаем куки с именем "username"
return response
@app.route('/get_cookie')
def get_cookie():
username = request.cookies.get('username') # Получаем значение куки
return f'Привет, {username}!' if username else 'Куки не найдены.'
if __name__ == '__main__':
app.run(debug=True)
Хранятся только во время работы браузера и удаляются после его закрытия.
Сохраняются на устройстве пользователя до истечения срока действия.
Передаются только через HTTPS для обеспечения безопасности.
Не доступны через JavaScript, используются для защиты от XSS-атак.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊28
В Python 3.11 были добавлены новые классы исключений
BaseExceptionGroup
и ExceptionGroup
. Эти классы решают проблему одновременной обработки нескольких исключений, которые могут возникать в сложных ситуациях, таких как асинхронное программирование, многопоточность или обработка нескольких связанных ошибок. Давайте разберем, зачем они нужны, как их использовать и какие преимущества они дают.Ранее в Python было возможно выбросить только одно исключение за раз, и обработка нескольких исключений одновременно требовала сложного и неочевидного кода. Например:
При работе с асинхронными функциями или потоками может возникнуть сразу несколько ошибок, и их нужно корректно обработать.
В больших приложениях или библиотеках (например, при работе с
asyncio
) может быть необходимость передать сразу несколько исключений, которые произошли в разных местах, как единый объект.BaseExceptionGroup
и его подкласс ExceptionGroup
позволяют группировать несколько исключений и выбрасывать их вместе в виде одного объекта. Это делает код более читаемым, упрощает обработку и исключает необходимость ручной агрегации ошибок.BaseExceptionGroup
- это базовый класс для группировки исключений. Он наследуется от BaseException
и, как правило, не используется напрямую.ExceptionGroup
- это подкласс, который наследуется от Exception
. Этот класс используется для обработки групп исключений, которые возникают при обычных ошибках в коде (не фатальных).Классы исключений
BaseExceptionGroup
и ExceptionGroup
позволяют создать "группу исключений", которая содержит несколько отдельных исключений. Это полезно, когда вам нужно:Указать несколько ошибок одновременно.
Позволить обработчику исключений работать с каждым из них.
def task_1():
raise ValueError("Ошибка в задаче 1")
def task_2():
raise TypeError("Ошибка в задаче 2")
try:
# Создаем группу исключений
raise ExceptionGroup(
"Ошибки в задачах",
[ValueError("Ошибка в задаче 1"), TypeError("Ошибка в задаче 2")]
)
except ExceptionGroup as eg:
for exc in eg.exceptions:
print(f"Обнаружено исключение: {exc}")
Результат
Обнаружено исключение: Ошибка в задаче 1
Обнаружено исключение: Ошибка в задаче 2
При обработке
ExceptionGroup
можно использовать механизм фильтрации с помощью конструкции except*
. Это нововведение в Python 3.11 позволяет обрабатывать разные типы исключений внутри группы по-разному.try:
raise ExceptionGroup(
"Ошибки в задачах",
[ValueError("Ошибка 1"), TypeError("Ошибка 2"), ValueError("Ошибка 3")]
)
except* ValueError as ve:
print("Обрабатываем ValueError:", ve)
except* TypeError as te:
print("Обрабатываем TypeError:", te)
Результат
Обрабатываем ValueError: Ошибка 1
Обрабатываем ValueError: Ошибка 3
Обрабатываем TypeError: Ошибка 2
Вы можете объединить связанные ошибки и передать их в одном объекте.
Использование
except*
позволяет обработать каждое исключение из группы отдельно, не теряя гибкости.В асинхронных задачах (
asyncio
) часто возникает несколько ошибок одновременно, и их можно группировать для дальнейшей обработки.Код становится проще и понятнее, так как не нужно вручную собирать и разбирать исключения.
Когда вы работаете с несколькими задачами, которые могут порождать ошибки одновременно (например, асинхронный код).
Когда вы хотите сообщить о нескольких связанных ошибках, не выбрасывая каждую из них отдельно.
Когда требуется раздельная обработка разных типов ошибок.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
- В SQL: с помощью EXPLAIN, EXPLAIN ANALYZE;
- PostgreSQL: pg_stat_statements, auto_explain;
- MongoDB: db.setProfilingLevel(2) и system.profile;
- Также с помощью APM-инструментов (NewRelic, Datadog).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍4
В Python поиск переменной происходит по правилу LEGB, которое определяет порядок поиска в четырёх областях видимости:
Пример работы LEGB
x = "глобальная" # Global
def outer():
x = "охватывающая" # Enclosing
def inner():
x = "локальная" # Local
print(x) # Поиск начинается отсюда (L)
inner()
outer()
Вывод
локальная
Если нужно изменить глобальную переменную внутри функции, используем
global
x = 10 # Глобальная переменная
def modify_global():
global x
x = 20 # Меняем глобальную переменную
modify_global()
print(x) # 20
Если в вложенной функции нужно изменить переменную из enclosing-области, используем
nonlocal
def outer():
x = 10 # Переменная из enclosing-области
def inner():
nonlocal x
x = 20 # Меняем `x` в `outer()`
inner()
print(x) # 20
outer()
Если переменная не найдена в LEGB, Python выдаст
NameError
def func():
print(y) # Ошибка: y не объявлена!
func()
Ошибка
NameError: name 'y' is not defined
Python в последнюю очереде проверяет встроенные функции (
print()
, len()
, sum()
и т. д.). print = "Ошибка!" # Переопределили встроенную функцию
print("Hello") # TypeError: 'str' object is not callable
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
Алгоритм k ближайших соседей (k-NN) — это метод машинного обучения, используемый для классификации и регрессии. Он ищет k наиболее близких объектов к целевой точке (по метрике расстояния, например, евклидовой) и принимает решение на основе их меток. Это ленивый алгоритм, так как не обучается заранее, а работает прямо по данным.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊4👍3🔥3
Модуль
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
👍9💊2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍4
В Django миграции используются для изменения структуры базы данных (создание, изменение и удаление таблиц и полей).
Пример модели пользователя:
from django.db import models
class UserProfile(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
Запускаем команду:
python manage.py makemigrations
Django создаст файл миграции в
migrations/
migrations/
0001_initial.py # Файл с SQL-изменениями
Проверяем SQL-запрос, который будет выполнен
python manage.py sqlmigrate myapp 0001
После генерации нужно применить миграции к базе данных:
python manage.py migrate
Добавим поле в
models.py
class UserProfile(models.Model):
name = models.CharField(max_length=100)
age = models.IntegerField()
email = models.EmailField(default="example@example.com") # Добавили поле
Сгенерируем новую миграцию
python manage.py makemigrations
Применяем изменения к БД
python manage.py migrate
Если нужно откатить последнее изменение:
python manage.py migrate myapp 0001 # Откат до первой миграции
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔3
Да, можно использовать параметр update_fields.
Пример:
Это ускоряет запрос и уменьшает шанс перезаписи данных, особенно если используются сигналы или кастомная логика в save().
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔10💊2
Идемпотентность — это свойство операции, при котором повторное выполнение приводит к тому же результату, что и первое.
если операция выполнится повторно (из-за ошибки сети), она не приведёт к неожиданному результату.
позволяет избежать дублирования данных или неожиданных изменений.
гарантирует, что повторные вызовы API не создадут дубликатов.
В веб-разработке идемпотентность важна для API-запросов, чтобы случайные повторные вызовы не привели к непредсказуемым последствиям.
Этот запрос идемпотентен — если отправить его 10 раз, пользователь "Alice" останется тем же.
POST /users { "name": "Alice" }
В SQL запросы
SELECT
и DELETE
часто идемпотентны, а INSERT
— нет. DELETE FROM users WHERE id = 5;
Этот запрос идемпотентен — удаление пользователя с ID = 5 несколько раз не изменит систему (если он уже удалён).
INSERT INTO users (name) VALUES ('Alice');
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Редактирование данных в реляционных базах происходит с помощью SQL. Основные команды:
- INSERT для добавления.
- UPDATE для изменения.
- DELETE для удаления.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8💊5
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥7
Это поведенческий паттерн проектирования, который определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Паттерн "Стратегия" позволяет изменять алгоритмы независимо от клиентов, которые их используют.
Позволяет инкапсулировать различные алгоритмы и использовать их независимо.
Устраняет дублирование кода и упрощает классы, которые используют эти алгоритмы.
Легко добавлять новые алгоритмы или изменять существующие без изменения клиентского кода.
Интерфейс, определяющий общий метод, который должны реализовать все алгоритмы.
Реализации различных алгоритмов, которые реализуют интерфейс стратегии.
Класс, использующий стратегию для выполнения задачи.
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💊2
Это механизм обратного вызова (callback), позволяющий реагировать на события в Django. Они используются для:
- Действий после сохранения объекта (post_save)
- Удаления объектов (post_delete)
- Изменения данных пользователей (user_logged_in)
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥3🤔1
Это методология управления процессом создания программного обеспечения, которая включает в себя последовательность этапов и действий, необходимых для разработки, тестирования, развертывания и поддержки программных продуктов. Цель SDLC — обеспечить структурированный и эффективный подход к разработке ПО, минимизируя риски и повышая качество конечного продукта.
На этом этапе определяются цели проекта, анализируются потребности и требования к системе. Включает сбор требований от заинтересованных сторон, анализ бизнес-процессов и создание документации с описанием требований.
Встречи с клиентами и пользователями для определения функций системы. Документирование функциональных и нефункциональных требований.
На этапе проектирования разрабатывается архитектура системы и ее компоненты. Создаются технические спецификации, включая схемы базы данных, диаграммы классов и интерфейсов, а также детализируется план реализации.Разработка диаграмм UML.Создание прототипов пользовательского интерфейса.Проектирование архитектуры системы.
На этом этапе осуществляется непосредственная разработка программного обеспечения на основе спецификаций, созданных на предыдущем этапе. Кодирование выполняется в соответствии с выбранными языками программирования и инструментами разработки. Написание кода для модулей и компонентов системы. Интеграция различных компонентов системы. Регулярное использование систем контроля версий (например, Git).
Этап тестирования включает проверку и валидацию системы для обнаружения и исправления ошибок. Тестирование проводится в различных формах, включая юнит-тестирование, интеграционное тестирование, системное тестирование и приемочное тестирование. Автоматизированное тестирование с использованием фреймворков, таких как pytest или JUnit. Ручное тестирование функциональности и пользовательского интерфейса. Тестирование производительности и безопасности.
На этом этапе программное обеспечение разворачивается в рабочей среде и становится доступным пользователям. Включает настройку серверов, развертывание баз данных и настройку инфраструктуры. Развертывание на облачных платформах, таких как AWS или Azure. Настройка и конфигурация серверов и сетей. Миграция данных и начальная загрузка данных.
Этап поддержки и сопровождения включает в себя обслуживание и улучшение системы после ее развертывания. Включает исправление ошибок, обновление функциональности и оптимизацию производительности. Обновление системы безопасности. Внесение изменений на основе отзывов пользователей. Обслуживание серверов и баз данных.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2