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
Ниже пример простого скрипта на Python, который собирает новогоднее поздравление из случайно выбранных слов и фраз. Его можно расширять, добавлять дополнительные списки или логику по своему вкусу.


import random

def generate_new_year_greeting():
"""
Генерирует новогоднее поздравление, выбирая слова из списков случайным образом.
"""

# Приветствия/начальные фразы
starts = [
"Поздравляю",
"Сердечно поздравляю",
"От всей души приветствую",
"С огромной радостью поздравляю"
]

# Прилагательные/эпитеты
adjectives = [
"счастливого",
"волшебного",
"радостного",
"прекрасного",
"блестящего"
]

# Основные пожелания
wishes = [
"здоровья",
"удачи",
"радости",
"любви",
"тепла",
"творческих успехов",
"исполнения всех желаний"
]

# Дополнительные фразы
extras = [
"чтобы каждый день был наполнен чудесами",
"пусть все мечты сбываются",
"желаю верить в себя и покорять любые вершины",
"пусть в сердце живёт только добро",
"и пусть этот год принесёт много ярких событий"
]

# Заключительные фразы/пожелания
endings = [
"С Новым годом!",
"Пусть в этом году будет всё на высоте!",
"Пусть в новом году будет только лучше!",
"С праздником!",
"Свершений и новых побед!"
]

# Собираем предложение
greeting = (
f"{random.choice(starts)} с наступившим {random.choice(adjectives)} Новым годом!\n\n"
f"Желаю {random.choice(wishes)}, {random.choice(wishes)}, а также {random.choice(wishes)}.\n"
f"И, конечно, {random.choice(extras)}.\n\n"
f"{random.choice(endings)}"
)

return greeting

def main():
# Генерируем и выводим поздравление
print(generate_new_year_greeting())

if __name__ == "__main__":
main()


### Как это работает:
1. Списки со словами и фразами: Для разных частей поздравления (`starts`, adjectives, wishes, extras, `endings`) заведены отдельные списки.
2. Модуль `random`: При помощи random.choice выбирается по одной фразе/слову из каждого списка.
3. Сборка текста: Формируем итоговую строку (`greeting`), используя f-строки с подстановками.
4. Вывод результата: Вызов print(generate_new_year_greeting()) выдаёт нам случайное поздравление на каждом запуске.

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

Подпишись 👉🏻 @KodduuPython 🤖
👍84
Ниже приведён шуточный пример кода на Python, который «оценивает», сколько салата «Оливье» было съедено во всём мире на Новый год. Все расчёты, конечно, условны и сделаны для иллюстрации, а не на основе реальной статистики.


import random

def estimate_olivier_eaten():
"""
Возвращает приблизительное (и шуточное) количество килограммов Оливье,
которые были съедены на планете в новогоднюю ночь.
"""

# (1) Численность населения (приблизительно, в миллиардах)
world_population = 8.05 # млрд (примерно к 2024 году)

# (2) Процент людей, отмечающих Новый год
# Условно предположим, что его празднуют 80% населения
celebrating_people_percent = 0.8

# (3) Процент любителей Оливье среди тех, кто празднует
# Пусть из празднующих минимум 50% едят Оливье
olivier_lovers_percent = 0.5

# (4) Средняя порция Оливье на человека (в граммах)
# Предположим 300 г на душу – кто-то съест больше, кто-то меньше
avg_portion_per_person_grams = 300

# (5) Считаем
# Сколько людей ест Оливье
number_of_olivier_eaters = world_population * 1_000_000_000 \
* celebrating_people_percent \
* olivier_lovers_percent

# Сколько всего граммов Оливье пришлось на этих людей
total_grams_olivier = number_of_olivier_eaters * avg_portion_per_person_grams

# Переводим в килограммы
total_kilos_olivier = total_grams_olivier / 1000

return total_kilos_olivier

def main():
# Получим оценку
kilos_olivier = estimate_olivier_eaten()

# Для «дополнительной реалистичности» внесём случайный разброс ±10%
# Ведь точное число никто не знает 🙂
fluctuation_percent = random.uniform(-0.1, 0.1)
kilos_olivier *= (1 + fluctuation_percent)

# Красиво форматируем число (например, с разделением разрядов)
result_str = f"{kilos_olivier:,.0f}" # округлим до целых
print(f"По приблизительным (шуточным) оценкам, в новогоднюю ночь "
f"на планете было съедено около {result_str} кг Оливье!")

if __name__ == "__main__":
main()


### Как работает код

1. Параметры «мировой» статистики
- world_population — приблизительная численность населения Земли в миллиардах.
- celebrating_people_percent — доля тех, кто отмечает Новый год.
- olivier_lovers_percent — доля тех, кто в праздничную ночь ест Оливье (из тех, кто вообще празднует).

2. Средняя порция
В примере для простоты взято \(300\) граммов на человека. Кто-то съедает больше, кто-то меньше — но пусть будет так.

3. Вычисление
- Находим общее число людей, которые (гипотетически) ели Оливье.
- Умножаем на 300 г.
- Переводим всё это в килограммы.

4. Случайный разброс
В коде мы добавляем ±10% (переменная `fluctuation_percent`), чтобы сделать оценку ещё менее «точной» и более шутливой.

5. Вывод
В main() печатаем итоговое «псевдо-число» в красиво отформатированном виде.

---

Это, конечно, не настоящее научное исследование, а лишь пример того, как можно реализовать в Python «виртуальный счётчик» чего угодно — например, салата Оливье в новогоднюю ночь.

Подпишись 👉🏻 @KodduuPython 🤖
51
Ниже приведён упрощённый пример на Python, демонстрирующий базовые идеи, которые могли использоваться для плановых расчётов в экономике (как, например, в СССР). Он не претендует на историческую точность и полноту, но иллюстрирует общий подход к задачам планирования с применением математической оптимизации.

---

Краткое введение в задачу

Предположим, что у нас есть несколько типов ресурсов (например, металл, дерево, электроэнергия и т.д.), и мы хотим произвести несколько видов товаров (станки, мебель, автомобили и т.д.). У каждого товара есть:
1. План по выпуску (то есть минимальное количество, которое нужно произвести по указу «сверху»).
2. Потребление ресурсов на единицу выпуска (например, один автомобиль требует 1 тонну металла, 10 кВт⋅ч электроэнергии и т.п.).
3. Ограниченное количество ресурсов, доступных в нашей «народно-хозяйственной» системе.

Основная задача: найти, сколько каждого вида товара нужно произвести, чтобы:
- Выполнить (или превысить) плановые задания (заказ государства).
- Не превысить доступные объёмы ресурсов.
- Максимизировать (или минимизировать) некую целевую функцию — например, суммарную “пользу” (удовлетворение потребностей народа / вклад в экономику).

В реальном СССР и других плановых экономиках задач было в разы больше и сложнее: расчёты производились по десяткам тысяч наименований продукции, учитывалась логистика, взаимозаменяемость ресурсов, отраслевые приоритеты и т.д. В 70–80-х годах это было крайне затруднительно из-за недостатка вычислительной техники и несовершенства методов планирования, что приводило к неточностям, дефицитам и дисбалансам.

Сегодня же, используя современные вычислительные мощности и продвинутые алгоритмы (линейное и нелинейное программирование, машинное обучение, системы принятия решений в реальном времени и т.п.), можно в теории гораздо эффективнее решать плановые задачи. Хотя, конечно, сама концепция плановой экономики поднимает множество вопросов и проблем, выходящих за рамки чисто вычислительной стороны дела.

Сложность плановых расчётов в 70–80-х

Недостаток вычислительной техники. ЭВМ в СССР (например, «Минск», «Урал», ЕС ЭВМ) имели на порядки меньшую производительность по сравнению с современными ПК. В 70–80-е годы такие машины могли обрабатывать относительно простые и не слишком большие задачи. Полноценный учёт сотен тысяч наименований товаров и ресурсов представлял колоссальную computational-проблему.
Ручной труд экономистов и плановиков. Многие расчёты производились вручную, с помощью арифмометров, перфокарт. Часть плановых заданий корректировалась “на местах”, что приводило к искажению общей картины.
Ограничения математических моделей. Методологии линейного программирования, многокритериальной оптимизации и т. п. тогда не были развиты так широко, как сейчас. Вдобавок многие экономические и социальные факторы трудно формализовать линейной моделью.
В результате получался грубый (и часто запаздывающий) план, который вёл к дефициту одних товаров и избытку других, очередям, бартерным схемам и так далее.

Подпишись 👉🏻 @KodduuPython 🤖
## Пример кода на Python

Для решения подобных задач часто применяют библиотеки для линейного программирования (Linear Programming). Одна из популярных библиотек в Python — PuLP. Если её нет, установите командой:

pip install pulp


Ниже приведён пример задачи, где мы хотим произвести три вида продукции: A, B и C.
- Каждый вид продукции требует определённое количество ресурсов (R1 и R2).
- Есть плановый минимум по каждому товару.
- Есть ограничения на объём ресурсов.
- Мы хотим максимизировать так называемую “общественную пользу” (условный показатель важности каждого товара).

### Код


# Пример кода, иллюстрирующего подход к задаче планирования

from pulp import LpProblem, LpMaximize, LpVariable, LpInteger, lpSum, LpStatus, value

# Создаём задачу линейного программирования (ЛП)
problem = LpProblem("SovietPlan", LpMaximize)

# Объявим переменные:
# xA, xB, xC — количество единиц продукции A, B и C, которое мы собираемся произвести.
# для наглядности используем целочисленное программирование (LpInteger),
# хотя в реальности могут быть и вещественные переменные.
xA = LpVariable('xA', lowBound=0, cat=LpInteger)
xB = LpVariable('xB', lowBound=0, cat=LpInteger)
xC = LpVariable('xC', lowBound=0, cat=LpInteger)

# Плановые задания (минимальное количество, которое нужно произвести)
planA = 10
planB = 20
planC = 5

# Коэффициенты потребления ресурсов на единицу каждого товара.
# Пусть ресурс R1 (например, металл) и ресурс R2 (например, электроэнергия).
# Допустим, на производство 1 единицы A нужно 3 ед. R1 и 1 ед. R2,
# на производство 1 единицы B — 2 ед. R1 и 2 ед. R2,
# на производство 1 единицы C — 4 ед. R1 и 3 ед. R2
r1_for_A = 3
r2_for_A = 1

r1_for_B = 2
r2_for_B = 2

r1_for_C = 4
r2_for_C = 3

# Доступное количество ресурсов
R1_available = 100 # например, 100 тонн металла
R2_available = 90 # например, 90 кВт⋅ч условной электроэнергии

# "Польза" (или приоритет) от каждой единицы товара
# В реальном случае это могло бы учитывать потребности населения,
# важность для военной промышленности, экспортный потенциал и т.п.
benefitA = 5
benefitB = 4
benefitC = 6

# Целевая функция: максимизируем суммарную "пользу"
problem += (benefitA * xA + benefitB * xB + benefitC * xC), "Total_Benefit"

# Добавим ограничения

# 1. Выполнение плановых заданий
problem += xA >= planA, "Min_A"
problem += xB >= planB, "Min_B"
problem += xC >= planC, "Min_C"

# 2. Ограничение по ресурсам
problem += (r1_for_A * xA + r1_for_B * xB + r1_for_C * xC) <= R1_available, "Res_R1"
problem += (r2_for_A * xA + r2_for_B * xB + r2_for_C * xC) <= R2_available, "Res_R2"

# Решаем задачу
problem.solve()

# Вывод результатов
print(f"Статус решения: {LpStatus[problem.status]}")
print(f"Оптимальное количество продукции A (xA): {xA.varValue}")
print(f"Оптимальное количество продукции B (xB): {xB.varValue}")
print(f"Оптимальное количество продукции C (xC): {xC.varValue}")
print(f"Максимальная польза: {value(problem.objective)}")


### Интерпретация результатов

1. Статус решения может показать, что задача решена оптимально (`Optimal`) или что оптимального решения нет (если, например, требования слишком высоки и ресурсы не позволяют их удовлетворить).
2. Количество продукции (xA, xB, xC) — сколько штук каждого товара в итоге планируется выпускать.
3. Максимальная польза (value(problem.objective)) показывает значение целевой функции.

Подпишись 👉🏻 @KodduuPython 🤖
Ниже приведу пример задачи из современной практики, которая по своей структуре напоминает упрощённую модель плановой экономики, но уже в контексте цепочек поставок (Supply Chain). Это одна из наиболее распространённых и сложных задач в современной логистике и экономике. В реальных условиях такие задачи включают сотни (а то и тысячи) складов, фабрик, пунктов потребления, видов транспорта и видов продукции.

Пример:
- Есть два завода (Factory1, Factory2), на которых производятся два вида товаров (Product A и Product B).
- Есть два распределительных центра (склада) (DC1, DC2).
- Есть два региона с конечным спросом (Market1, Market2).
- Мы знаем спрос в каждом регионе по каждому товару, ограничения по мощности заводов (сколько каждого товара они могут произвести) и ёмкость складов (сколько там можно держать товаров).
- Мы хотим минимизировать совокупные затраты (произвести товар, перевезти с завода на склад, затем со склада — к конечному потребителю).

Подобная постановка задачи — задача оптимизации в цепочке поставок (supply chain optimization), которая, как и плановая задача, может вырасти до огромных масштабов и требовать значительных вычислительных ресурсов.

---

## Иллюстративный пример на Python (используем библиотеку PuLP)

> Для решения потребуется библиотека PuLP. Установить её можно командой:
>

> pip install pulp
>



from pulp import (
LpProblem, LpMinimize, LpVariable, LpStatus, lpSum, LpInteger, value
)

# ---------------------------
# 1. ДАННЫЕ ЗАДАЧИ
# ---------------------------

# Заводы (factories), Склады (distribution centers), Рынки/регионы (markets)
factories = ["Factory1", "Factory2"]
distribution_centers = ["DC1", "DC2"]
markets = ["Market1", "Market2"]
products = ["ProductA", "ProductB"]

# Производственные мощности (максимальное кол-во единиц товара,
# которое может быть выпущено на каждом заводе)
# form: capacity[завод][продукт]
capacity = {
"Factory1": {"ProductA": 100, "ProductB": 80},
"Factory2": {"ProductA": 120, "ProductB": 100}
}

# Ёмкость складов (сколько всего единиц любых товаров может храниться на складе)
# form: dc_capacity[склад]
dc_capacity = {
"DC1": 150,
"DC2": 150
}

# Спрос в регионах (сколько единиц каждого товара нужно в каждом рынке)
# form: demand[рынок][продукт]
demand = {
"Market1": {"ProductA": 60, "ProductB": 40},
"Market2": {"ProductA": 80, "ProductB": 70}
}

# Себестоимость производства (cost of production) на каждом заводе
# form: production_cost[завод][продукт]
production_cost = {
"Factory1": {"ProductA": 2.0, "ProductB": 3.0},
"Factory2": {"ProductA": 2.5, "ProductB": 2.8}
}

# Стоимость транспортировки с завода до склада (за 1 единицу товара)
# form: transport_cost_factory_dc[(завод, склад)]
transport_cost_factory_dc = {
("Factory1", "DC1"): 0.5,
("Factory1", "DC2"): 0.6,
("Factory2", "DC1"): 0.7,
("Factory2", "DC2"): 0.4
}

# Стоимость транспортировки со склада к рынку (за 1 единицу товара)
# form: transport_cost_dc_market[(склад, рынок)]
transport_cost_dc_market = {
("DC1", "Market1"): 0.3,
("DC1", "Market2"): 0.8,
("DC2", "Market1"): 0.6,
("DC2", "Market2"): 0.5
}

# ---------------------------
# 2. ПОСТАНОВКА ЗАДАЧИ
# ---------------------------
# Создадим задачу линейного программирования: минимизация общих затрат
problem = LpProblem("SupplyChainOptimization", LpMinimize)

# ---------------------------
# 3. ПЕРЕМЕННЫЕ
# ---------------------------
# Пусть:
# x_fdc[p, f, dc] = количество товара p, производимого на заводе f,
# и отправляемого на склад dc
#
# y_dcm[p, dc, m] = количество товара p, отгружаемого со склада dc на рынок m

# Объявим переменные как неотрицательные целые (или неотрицательные непрерывные — зависит от контекста)
x_fdc = {}
for p in products:
for f in factories:
for dc in distribution_centers:
x_fdc[(p, f, dc)] = LpVariable(
f"x_{p}_{f}_{dc}",
lowBound=0,
cat='Continuous'
)
y_dcm = {}
for p in products:
for dc in distribution_centers:
for m in markets:
y_dcm[(p, dc, m)] = LpVariable(
f"y_{p}_{dc}_{m}",
lowBound=0,
cat='Continuous'
)

# ---------------------------
# 4. ЦЕЛЕВАЯ ФУНКЦИЯ
# ---------------------------
# Общие затраты = затраты на производство + затраты на перевозку от завода к складу + от склада к рынку
problem += lpSum(
production_cost[f][p] * x_fdc[(p, f, dc)]
+ transport_cost_factory_dc[(f, dc)] * x_fdc[(p, f, dc)]
for p in products
for f in factories
for dc in distribution_centers
) + lpSum(
transport_cost_dc_market[(dc, m)] * y_dcm[(p, dc, m)]
for p in products
for dc in distribution_centers
for m in markets
), "Total_Cost"

# ---------------------------
# 5. ОГРАНИЧЕНИЯ
# ---------------------------

# (A) Ограничения по производственным мощностям заводов:
# сумма отправленного товара p с завода f на все склады dc <= capacity[f][p]
for f in factories:
for p in products:
problem += lpSum(x_fdc[(p, f, dc)] for dc in distribution_centers) <= capacity[f][p], \
f"ProdCapacity_{f}_{p}"

# (B) Ограничения по ёмкости складов:
# на складе dc общее кол-во хранимых товаров (прибывших от всех заводов)
# не должно превышать dc_capacity[dc],
# но! нужно учесть, что то, что пришло на склад, может сразу уехать на рынок.
# Если мы считаем, что склад одновременно может хранить всё, что приходит,
# и лимит — это некая "пропускная способность", то упростим до:
# Σ(продуктов, заводов) x_fdc <= capacity_dc
# В реальности часто вводят дополнительные переменные для учёта запасов.
# Сделаем упрощённо.
for dc in distribution_centers:
problem += lpSum(x_fdc[(p, f, dc)] for p in products for f in factories) <= dc_capacity[dc], \
f"StorageCapacity_{dc}"

# (C) Баланс на складе (поток товаров через склад):
# кол-во товара p, пришедшее на склад dc, должно быть равно
# кол-ву, которое отгружается дальше в рынки (если мы предполагаем 0 складских запасов в конце).
# Σ(factories) x_fdc = Σ(markets) y_dcm
for dc in distribution_centers:
for p in products:
problem += lpSum(x_fdc[(p, f, dc)] for f in factories) == lpSum(y_dcm[(p, dc, m)] for m in markets), \
f"FlowBalance_{dc}_{p}"

# (D) Удовлетворение спроса в каждом рынке:
# Σ(dc) y_dcm >= demand[m][p]
for m in markets:
for p in products:
problem += lpSum(y_dcm[(p, dc, m)] for dc in distribution_centers) >= demand[m][p], \
f"Demand_{m}_{p}"

# ---------------------------
# 6. РЕШЕНИЕ ЗАДАЧИ
# ---------------------------
problem.solve()

# ---------------------------
# 7. ВЫВОД РЕЗУЛЬТАТОВ
# ---------------------------
print(f"Статус решения: {LpStatus[problem.status]}")
print(f"Минимальные совокупные затраты: {value(problem.objective):.2f}\n")

for (p, f, dc) in x_fdc:
qty = x_fdc[(p, f, dc)].varValue
if qty > 0:
print(f"Производство {p} на {f}, отправка на {dc}: {qty}")

for (p, dc, m) in y_dcm:
qty = y_dcm[(p, dc, m)].varValue
if qty > 0:
print(f"Отгрузка {p} со склада {dc} в {m}: {qty}")


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

Подпишись 👉🏻 @KodduuPython 🤖
6
Ниже приведён пример кода на Python, иллюстрирующего «задачу о маршрутах Деда Мороза» (упрощённая версия задачи коммивояжёра). В ней мы хотим найти оптимальный маршрут Деда Мороза, чтобы он мог доставить подарки в несколько домов (точек на карте), начиная и заканчивая в условном «Лапландском логистическом центре» (или просто в «домике Деда Мороза»).

Здесь мы используем библиотеку OR-Tools от Google (а не `pulp`). Если библиотеки нет, установите её:

pip install ortools


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


from ortools.constraint_solver import routing_enums
from ortools.constraint_solver import pywrapcp

def create_data_model():
"""
Создаём структуру с входными данными.
distance_matrix: матрица расстояний между всеми точками (0-я точка — «Лапландия»).
num_vehicles: количество "транспортных средств" (один Дед Мороз).
depot: индекс начальной/конечной точки (тоже «Лапландия»).
"""
data = {}

# Пример: у нас есть 6 домов + 1 "домик Деда Мороза" (всего 7 точек).
# Матрицу расстояний можно задать произвольно или сгенерировать.
# Ниже — условный пример (симметричная матрица).
data['distance_matrix'] = [
# От каждой точки до каждой (0-я строка — расстояния из «Лапландии»).
[0, 10, 15, 20, 25, 30, 12], # Lapland (0) -> ...
[10, 0, 18, 13, 28, 15, 22], # House1 (1) -> ...
[15, 18, 0, 17, 16, 22, 15], # House2 (2)
[20, 13, 17, 0, 14, 19, 23], # House3 (3)
[25, 28, 16, 14, 0, 25, 20], # House4 (4)
[30, 15, 22, 19, 25, 0, 18], # House5 (5)
[12, 22, 15, 23, 20, 18, 0 ], # House6 (6)
]
data['num_vehicles'] = 1 # Дед Мороз «один»
data['depot'] = 0 # Начальная (и конечная) точка — 0, то есть «Лапландия»
return data

def main():
# Создаём данные
data = create_data_model()
distance_matrix = data['distance_matrix']
num_locations = len(distance_matrix) # Всего точек (включая «Лапландию»)
num_vehicles = data['num_vehicles']
depot = data['depot']

# Создаём менеджер маршрутов и модель
manager = pywrapcp.RoutingIndexManager(
num_locations, # кол-во локаций (вершин)
num_vehicles, # кол-во «трансп. средств»
depot # индекс депо (старт/финиш)
)

routing = pywrapcp.RoutingModel(manager)

# Функция-«коллбек», возвращающая расстояние между двумя точками
def distance_callback(from_index, to_index):
# Преобразуем внутренние индексы маршрутизатора в индексы из матрицы
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return distance_matrix[from_node][to_node]

# Регистрируем функцию коллбека и присваиваем ей ID
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

# Зададим параметры поиска (например, стратегию поиска маршрута)
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums.FirstSolutionStrategy.PATH_CHEAPEST_ARC
)

# По желанию — включим какую-нибудь эвристику локального поиска
# search_parameters.local_search_metaheuristic = (
# routing_enums.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
# )
# search_parameters.time_limit.seconds = 5 # ограничение по времени

# Запускаем решение
solution = routing.SolveWithParameters(search_parameters)
if solution:
# Выводим итоговый маршрут
print("Оптимальный маршрут Деда Мороза (минимальное суммарное расстояние):")
index = routing.Start(0) # начинаем с депо (Лапландия)
plan_output = "Лапландия -> "
route_distance = 0
while not routing.IsEnd(index):
next_index = solution.Value(routing.NextVar(index))
route_distance += routing.GetArcCostForVehicle(index, next_index, 0)
plan_output += f"House{manager.IndexToNode(next_index)} -> "
index = next_index
plan_output += "Лапландия (конец)"
print(plan_output)
print(f"Общее расстояние: {route_distance}")
else:
print("Решение не найдено!")

if __name__ == '__main__':
main()


### Пояснения

1. OR-Tools — это мощная библиотека от Google для решения задач оптимизации (в том числе маршрутизации, линейного и целочисленного программирования, расписаний и т. д.).
2. Ключевые моменты:
- distance_matrix: матрица расстояний между всеми точками (включая точку «Лапландии», где начинается и заканчивается маршрут).
- RoutingIndexManager и RoutingModel: объекты, которые отвечают за «оптимизационную модель».
- distance_callback: функция, которая для каждой пары «откуда–куда» возвращает расстояние.
- В конце мы получаем итоговый маршрут (последовательность посещения домов), чтобы суммарное расстояние было минимальным.

3. Мы предположили, что Дед Мороз должен объехать все дома (узлы) один раз и вернуться в исходную точку (в классической постановке — задача коммивояжёра). В результате мы ищем маршрут, минимизирующий общее расстояние путешествия.

4. В реальном мире можно добавлять множество дополнительных условий:
- Временные окна (должен доставить подарок до определённого времени).
- Ограничения по весу и объёму подарков (если у Деда Мороза несколько волшебных саней).
- Разные скорости движения или разные стоимости поездки (например, снежные заносы).

Но даже в таком упрощённом виде пример показывает, как другая библиотека (OR-Tools), а не PuLP, применяется для решения оптимизационной задачи на тему «доставки подарков Дедом Морозом».

Подпишись 👉🏻 @KodduuPython 🤖
🔥5
NetworkX — это удобная и мощная библиотека для работы с графами на Python. С её помощью можно:

- Создавать графы (ориентированные и неориентированные)
- Добавлять вершины и рёбра
- Находить кратчайшие пути (алгоритмы Дейкстры, Беллмана — Форда и др.)
- Искать связные компоненты, вычислять центральности, кластеризации и многое другое

Ниже — короткий пример, где мы создаём простой граф, добавляем рёбра и ищем кратчайший путь между двумя узлами:


import networkx as nx

# Создадим неориентированный граф
G = nx.Graph()

# Добавим вершины (можно неявно при добавлении рёбер)
G.add_nodes_from(["A", "B", "C", "D", "E"])

# Добавим рёбра с весами
G.add_edge("A", "B", weight=2)
G.add_edge("A", "C", weight=5)
G.add_edge("B", "D", weight=3)
G.add_edge("C", "D", weight=1)
G.add_edge("D", "E", weight=4)

# Ищем кратчайший путь (по весам) из A в E
path = nx.dijkstra_path(G, source="A", target="E", weight="weight")
distance = nx.dijkstra_path_length(G, source="A", target="E", weight="weight")

print("Кратчайший путь A -> E:", path)
print(f"Общая длина пути: {distance}")


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

Подпишись 👉🏻 @KodduuPython 🤖
🔥2👍1
Вышла новая статья на pikabu "Как стать АйТишником в 2025 году (пошаговый план)". Суммировал опыт многих, кто пришел в ИТ из других сфер.

Подпишись 👉🏻 @KodduuPython 🤖
🔥5👍21
Ниже приведён прикладной пример использования библиотеки NetworkX для решения простой задачи на графах: представим, что у нас есть небольшая сеть дорог в городе, и мы хотим найти самый быстрый маршрут от склада до магазина с учётом скоростей на участках дорог.

- Узлы графа (nodes) — это перекрёстки.
- Рёбра графа (edges) — это дороги между перекрёстками.
- У каждого ребра есть:
- длина дороги (в километрах),
- скорость (км/ч), с которой можно проехать этот участок.

Целевая метрика: время в пути (в часах). Мы хотим найти кратчайший (по времени) путь, а не по географическому расстоянию.

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


import networkx as nx

def build_city_graph():
"""
Создаёт и возвращает ориентированный граф (DiGraph) с атрибутами:
- distance (км)
- speed (км/ч)
"""
G = nx.DiGraph()

# Добавим несколько перекрёстков (можно просто добавлять рёбра,
# тогда вершины создадутся автоматически)
intersections = ["Warehouse", "A", "B", "C", "Store"]
G.add_nodes_from(intersections)

# Добавим дороги (рёбра) с атрибутами:
# G.add_edge(откуда, куда, distance=..., speed=...)
G.add_edge("Warehouse", "A", distance=3.0, speed=30.0)
G.add_edge("Warehouse", "B", distance=5.0, speed=40.0)
G.add_edge("A", "C", distance=2.0, speed=20.0)
G.add_edge("B", "C", distance=2.5, speed=35.0)
G.add_edge("C", "Store", distance=4.0, speed=40.0)
G.add_edge("A", "Store", distance=8.0, speed=60.0)

# Можно добавить и обратные направления, если дороги двусторонние
G.add_edge("A", "Warehouse", distance=3.0, speed=30.0)
G.add_edge("B", "Warehouse", distance=5.0, speed=40.0)
# И так далее...

return G

def compute_travel_time(u, v, data):
"""
Вычисляем время (часы) проезда по участку (u->v) на основе атрибутов distance и speed.
data — словарь атрибутов ребра.
"""
dist = data.get("distance", 1.0)
spd = data.get("speed", 1.0)
return dist / spd # время = расстояние/скорость

def main():
# 1. Строим граф
G = build_city_graph()

# 2. Считаем «вес» каждого ребра как время
# Для поиска кратчайшего пути по времени используем атрибуты distance и speed.
# NetworkX позволяет указать коллбэк (функцию), которая вычисляет вес «на лету»,
# но здесь, для наглядности, прямо создадим новый атрибут "time".
for u, v, data in G.edges(data=True):
data["time"] = compute_travel_time(u, v, data)

# 3. Ищем кратчайший маршрут по атрибуту "time"
start = "Warehouse"
end = "Store"

# Используем алгоритм Дейкстры (dijkstra_path) или любой другой
path = nx.dijkstra_path(G, source=start, target=end, weight="time")
total_time = nx.dijkstra_path_length(G, source=start, target=end, weight="time")

print("Самый быстрый маршрут:", " -> ".join(path))
print(f"Общее время в пути (часы): {total_time:.2f}")

if __name__ == "__main__":
main()


### Что происходит в коде?

1. build_city_graph() — создаёт ориентированный граф (DiGraph). Каждая дорога (ребро) имеет:
- distance: длина участка (км),
- speed: доступная скорость движения (км/ч).

2. compute_travel_time() — функция для расчёта времени в пути (в часах) = \(\text{distance} / \text{speed}\).

3. Мы в цикле по всем рёбрам графа (G.edges(data=True)) создаём новый атрибут time, который потом используется в алгоритме Дейкстры.

4. nx.dijkstra_path и nx.dijkstra_path_length — стандартные методы NetworkX для нахождения кратчайшего пути и его «стоимости» (суммы весов) в взвешенном графе:
- source=start, target=end, weight="time" указывает, что в качестве веса ребра следует использовать именно атрибут time.

5. На выходе — маршрут (список перекрёстков) и итоговое время.

NetworkX даёт удобный способ моделировать любые сетевые структуры (дорожные сети, социальные графы, электрические сети и т. д.), используя множество готовых алгоритмов (поиск кратчайшего пути, анализ центральности, минимальное остовное дерево, поиск компонент связности и многое другое).

Подпишись 👉🏻 @KodduuPython 🤖
👍71
До 12 января действует скидка на программу Junior Python Developer и Data Scientist +интервью тесты 🔥🔥🔥

Программа включает в себя курс по Python, по Python Data Sceince, CookBook для практики Python и "Топ 100 вопросов с реальных собеседований по Python (+тесты)" 🔥🔥🔥

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



import pennylane as qml
from pennylane import numpy as np

# Создаем устройство с двумя кубитами
dev = qml.device("default.qubit", wires=2)

# Определяем квантовую схему
@qml.qnode(dev)
def circuit(param):
# Применяем поворот к первому кубиту
qml.RX(param, wires=0)
# Запутываем кубиты с помощью операции CNOT
qml.CNOT(wires=[0, 1])
# Возвращаем ожидаемые значения операторов Паули Z для обоих кубитов
return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))

# Значение параметра, определяющее степень запутанности
param_value = np.pi / 2

# Выполняем квантовую схему и выводим результаты измерений
result = circuit(param_value)
print(result)


### Объяснение кода

1. Импорт библиотек: Импортируем необходимые модули из библиотеки PennyLane для работы с квантовыми схемами.
2. Создание устройства: Определяем квантовое устройство с двумя кубитами.
3. Определение квантовой схемы:
- Используется декоратор @qml.qnode(dev), чтобы создать квантовую схему.
- Применяется операция поворота к первому кубиту, что изменяет его состояние.
- Затем применяется операция CNOT, которая запутывает два кубита.
- Возвращаются ожидаемые значения операторов Паули Z для каждого кубита, что позволяет оценить их состояния после измерения.
4. Выполнение схемы: Устанавливаем значение параметра для максимизации запутанности и выводим результаты измерений.

Подпишись 👉🏻 @KodduuPython 🤖
Вот пример кода на Python, который показывает основные частицы Стандартной модели, их категории и основные различия:


class Particle:
def __init__(self, name, type_, charge, mass, spin):
self.name = name
self.type_ = type_
self.charge = charge
self.mass = mass
self.spin = spin

def __str__(self):
return f"{self.name}: {self.type_}, Charge: {self.charge}, Mass: {self.mass} GeV/c², Spin: {self.spin}"


# Создаем частицы
particles = [
# Кварки
Particle("Up", "Quark", "+2/3", 0.0022, "1/2"),
Particle("Down", "Quark", "-1/3", 0.0047, "1/2"),
Particle("Charm", "Quark", "+2/3", 1.27, "1/2"),
Particle("Strange", "Quark", "-1/3", 0.096, "1/2"),
Particle("Top", "Quark", "+2/3", 173.1, "1/2"),
Particle("Bottom", "Quark", "-1/3", 4.18, "1/2"),

# Лептоны
Particle("Electron", "Lepton", "-1", 0.000511, "1/2"),
Particle("Electron Neutrino", "Lepton", "0", "<0.000001", "1/2"),
Particle("Muon", "Lepton", "-1", 0.105, "1/2"),
Particle("Muon Neutrino", "Lepton", "0", "<0.000001", "1/2"),
Particle("Tau", "Lepton", "-1", 1.777, "1/2"),
Particle("Tau Neutrino", "Lepton", "0", "<0.000001", "1/2"),

# Бозоны
Particle("Photon", "Boson", "0", "0", "1"),
Particle("W+", "Boson", "+1", 80.379, "1"),
Particle("W-", "Boson", "-1", 80.379, "1"),
Particle("Z", "Boson", "0", 91.1876, "1"),
Particle("Gluon", "Boson", "0", "0", "1"),
Particle("Higgs", "Boson", "0", 125.1, "0"),
]

# Группируем частицы по типу
grouped_particles = {}
for particle in particles:
grouped_particles.setdefault(particle.type_, []).append(particle)

# Выводим информацию о частицах
for type_, particles_list in grouped_particles.items():
print(f"{type_}s:")
for particle in particles_list:
print(f" - {particle}")
print()


### Вывод программы
Этот код создает объект Particle, который содержит свойства, такие как название, тип, заряд, масса и спин частицы. Затем он группирует частицы по категориям (кварки, лептоны, бозоны) и выводит их список.

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


Quarks:
- Up: Quark, Charge: +2/3, Mass: 0.0022 GeV/c², Spin: 1/2
- Down: Quark, Charge: -1/3, Mass: 0.0047 GeV/c², Spin: 1/2
...

Leptons:
- Electron: Lepton, Charge: -1, Mass: 0.000511 GeV/c², Spin: 1/2
- Electron Neutrino: Lepton, Charge: 0, Mass: <0.000001 GeV/c², Spin: 1/2
...

Bosons:
- Photon: Boson, Charge: 0, Mass: 0 GeV/c², Spin: 1
- W+: Boson, Charge: +1, Mass: 80.379 GeV/c², Spin: 1
...


Этот подход позволяет не только увидеть все частицы Стандартной модели, но и понять различия между ними по заряду, массе и спину.

Подпишись 👉🏻 @KodduuPython 🤖
21👍1
Вот пример кода на Python, который показывает, как из частиц Стандартной модели формируются атомы и молекулы.


class Particle:
def __init__(self, name, type_, charge, mass):
self.name = name
self.type_ = type_
self.charge = charge
self.mass = mass

class Proton:
def __init__(self):
self.quarks = [Particle("Up", "Quark", "+2/3", 0.0022),
Particle("Up", "Quark", "+2/3", 0.0022),
Particle("Down", "Quark", "-1/3", 0.0047)]
self.charge = "+1"

class Neutron:
def __init__(self):
self.quarks = [Particle("Up", "Quark", "+2/3", 0.0022),
Particle("Down", "Quark", "-1/3", 0.0047),
Particle("Down", "Quark", "-1/3", 0.0047)]
self.charge = "0"

class Atom:
def __init__(self, protons, neutrons, electrons):
self.protons = protons
self.neutrons = neutrons
self.electrons = electrons

def atomic_number(self):
return len(self.protons)

def mass_number(self):
return len(self.protons) + len(self.neutrons)

def is_neutral(self):
return len(self.protons) == len(self.electrons)

def __str__(self):
return (f"Atom: Atomic Number = {self.atomic_number()}, Mass Number = {self.mass_number()}, "
f"Neutral = {self.is_neutral()}")

class Molecule:
def __init__(self, atoms):
self.atoms = atoms

def molecular_formula(self):
element_count = {}
for atom in self.atoms:
symbol = f"Element-{atom.atomic_number()}"
element_count[symbol] = element_count.get(symbol, 0) + 1
return "".join(f"{symbol}{count if count > 1 else ''}" for symbol, count in element_count.items())

def __str__(self):
return f"Molecule: {self.molecular_formula()}"

# Пример: Создание атомов водорода и кислорода
hydrogen = Atom(protons=[Proton()], neutrons=[Neutron()], electrons=[Particle("Electron", "Lepton", "-1", 0.000511)])
oxygen = Atom(protons=[Proton() for _ in range(8)],
neutrons=[Neutron() for _ in range(8)],
electrons=[Particle("Electron", "Lepton", "-1", 0.000511) for _ in range(8)])

# Пример: Создание молекулы воды (H2O)
water = Molecule(atoms=[hydrogen, hydrogen, oxygen])

# Вывод информации
print(hydrogen)
print(oxygen)
print(water)


Этот код создает атомы, используя протоны, нейтроны и электроны, а затем объединяет атомы в молекулы.

Пример:

1. Атомы водорода и кислорода строятся из протонов, нейтронов и электронов.
2. Молекула воды (H₂O) создается из двух атомов водорода и одного атома кислорода.

Когда вы запустите этот код, вы получите вывод, показывающий структуру атомов и молекул. Например:

Atom: Atomic Number = 1, Mass Number = 2, Neutral = True
Atom: Atomic Number = 8, Mass Number = 16, Neutral = True
Molecule: Element-1H2Element-8O


Подпишись 👉🏻 @KodduuPython 🤖
Теперь код отображает принцип формирования Периодической таблицы Менделеева. Он включает создание элементов с их символами, названиями, атомными номерами и массами, а затем выводит их в упорядоченном виде. Вы можете запускать этот код, чтобы увидеть базовую структуру таблицы Менделеева.


class Particle:
def __init__(self, name, type_, charge, mass):
self.name = name
self.type_ = type_
self.charge = charge
self.mass = mass

class Proton:
def __init__(self):
self.quarks = [Particle("Up", "Quark", "+2/3", 0.0022),
Particle("Up", "Quark", "+2/3", 0.0022),
Particle("Down", "Quark", "-1/3", 0.0047)]
self.charge = "+1"

class Neutron:
def __init__(self):
self.quarks = [Particle("Up", "Quark", "+2/3", 0.0022),
Particle("Down", "Quark", "-1/3", 0.0047),
Particle("Down", "Quark", "-1/3", 0.0047)]
self.charge = "0"

class Atom:
def __init__(self, protons, neutrons, electrons):
self.protons = protons
self.neutrons = neutrons
self.electrons = electrons

def atomic_number(self):
return len(self.protons)

def mass_number(self):
return len(self.protons) + len(self.neutrons)

def is_neutral(self):
return len(self.protons) == len(self.electrons)

def __str__(self):
return (f"Atom: Atomic Number = {self.atomic_number()}, Mass Number = {self.mass_number()}, "
f"Neutral = {self.is_neutral()}")

class Element:
def __init__(self, symbol, name, atomic_number, atomic_mass):
self.symbol = symbol
self.name = name
self.atomic_number = atomic_number
self.atomic_mass = atomic_mass

def __str__(self):
return f"{self.symbol} ({self.name}): Atomic Number = {self.atomic_number}, Atomic Mass = {self.atomic_mass}"

class PeriodicTable:
def __init__(self):
self.elements = []

def add_element(self, element):
self.elements.append(element)

def display(self):
for element in sorted(self.elements, key=lambda e: e.atomic_number):
print(element)

# Создание элементов
hydrogen = Element("H", "Hydrogen", 1, 1.008)
helium = Element("He", "Helium", 2, 4.0026)
lithium = Element("Li", "Lithium", 3, 6.94)
beryllium = Element("Be", "Beryllium", 4, 9.0122)
boron = Element("B", "Boron", 5, 10.81)
carbon = Element("C", "Carbon", 6, 12.011)
nitrogen = Element("N", "Nitrogen", 7, 14.007)
oxygen = Element("O", "Oxygen", 8, 15.999)
fluorine = Element("F", "Fluorine", 9, 18.998)
neon = Element("Ne", "Neon", 10, 20.180)

# Создание таблицы Менделеева
periodic_table = PeriodicTable()
periodic_table.add_element(hydrogen)
periodic_table.add_element(helium)
periodic_table.add_element(lithium)
periodic_table.add_element(beryllium)
periodic_table.add_element(boron)
periodic_table.add_element(carbon)
periodic_table.add_element(nitrogen)
periodic_table.add_element(oxygen)
periodic_table.add_element(fluorine)
periodic_table.add_element(neon)

# Вывод таблицы
periodic_table.display()


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


import random

# Базовые элементы языка
nouns = ["человек", "кошка", "собака", "дерево", "река", "птица"]
verbs = ["идёт", "бежит", "летит", "плавает", "прыгает", "поёт"]
adjectives = ["красивый", "быстрый", "медленный", "зелёный", "громкий", "маленький"]
prepositions = ["на", "в", "под", "за", "перед", "около"]

# Функция для создания случайного предложения
def generate_sentence():
noun1 = random.choice(nouns)
noun2 = random.choice(nouns)
verb = random.choice(verbs)
adjective = random.choice(adjectives)
preposition = random.choice(prepositions)

# Создание структуры предложения
sentence = f"{noun1.capitalize()} {verb} {preposition} {adjective} {noun2}."
return sentence

# Генерация нескольких предложений
for _ in range(5):
print(generate_sentence())


### Пример вывода:

Кошка летит перед красивый человек.
Птица прыгает на громкий собака.
Человек идёт за зелёный река.
Собака поёт под маленький дерево.
Дерево плавает в быстрый птица.


Этот код демонстрирует основу синтаксиса языка: существительные, глаголы, прилагательные и предлоги объединяются в осмысленные структуры. Конечно, он использует случайность и не обладает глубиной реального языка, но показывает принципы.

Подпишись 👉🏻 @KodduuPython 🤖
👍31🤔1