Переработан интерфейс программы, расчёт занчений в процессе исправления.

This commit is contained in:
2026-05-18 15:53:24 +05:00
parent e6e86e50a3
commit 3ddd05acff
38 changed files with 2820 additions and 3555 deletions
+211
View File
@@ -0,0 +1,211 @@
"""
Расчёт питательных сред
Этот модуль содержит функции для расчёта состава питательных сред
на основе процентов, коэффициентов конверсии и разбавления.
Основная функция: calculate_medium_composition()
"""
from typing import List, Dict, Tuple
# Константы для конверсии единиц измерения
# Базовые единицы: мкл для объёма, мг для массы
VOLUME_UNITS = {
'нл': 0.001, # нанолитры -> микролитры
'мкл': 1.0, # микролитры (база)
'мл': 1000.0, # миллилитры -> микролитры
'л': 1000000.0, # литры -> микролитры
}
MASS_UNITS = {
'нг': 0.000001, # нанограммы -> миллиграммы
'мкг': 0.001, # микрограммы -> миллиграммы
'мг': 1.0, # миллиграммы (база)
'г': 1000.0, # граммы -> миллиграммы
'кг': 1000000.0, # килограммы -> миллиграммы
}
def convert_units(value: float, from_unit: str, to_unit: str = None) -> float:
"""
Конвертирует значение между единицами объёма или массы
Параметры:
value: числовое значение
from_unit: исходная единица (например "мл" или "мг")
to_unit: целевая единица (если None, конвертирует в базовую)
Возвращает:
float: сконвертированное значение
Пример:
>>> convert_units(100, 'мл') # конвертирует в базовую (мкл)
100000.0
>>> convert_units(500, 'мкл', 'мл')
0.5
"""
# Определяем тип единицы (объём или масса)
if from_unit in VOLUME_UNITS:
units_map = VOLUME_UNITS
elif from_unit in MASS_UNITS:
units_map = MASS_UNITS
else:
raise ValueError(f"Неизвестная единица измерения: {from_unit}")
# Конвертируем в базовую единицу (мкл для объёма, мг для массы)
value_in_base = value * units_map[from_unit]
# Если нужна конвертация в другую единицу
if to_unit and to_unit in units_map:
return value_in_base / units_map[to_unit]
return value_in_base
def calculate_medium_composition(
total_volume: float,
volume_unit: str,
reagents: List[Dict],
solvent_name: str = "Вода"
) -> Dict:
"""
РАССЧИТЫВАЕТ СОСТАВ ПИТАТЕЛЬНОЙ СРЕДЫ
Эта функция является основной для расчёта питательных сред.
ВХОДНЫЕ ПАРАМЕТРЫ:
---------------
total_volume : float
Общий объём/количество среды (например 1000)
volume_unit : str
Единица измерения общего объёма: "нл", "мкл", "мл", "л"
reagents : List[Dict]
Список реагентов. Каждый реагент - словарь с ключами:
- name (str): название реагента
- percentage (float): процентное содержание в среде (0-100)
- unit (str): единица измерения реагента (нг, мкг, мг, г, кг, нл, мкл, мл, л)
- dilution_factor (float): фактор разбавления (необяз., по умолч. 1.0)
Пример реагента:
{
'name': 'Глюкоза',
'percentage': 2.5,
'unit': 'г',
'dilution_factor': 1.0
}
solvent_name : str, optional
Название растворителя (по умолчанию "Вода")
ВОЗВРАЩАЕМЫЙ СЛОВАРЬ:
--------------------
{
'total_volume': float, # Исходный объём
'total_unit': str, # Единица измерения
'solvent_name': str, # Название растворителя
'solvent_volume': float, # Объём растворителя
'solvent_percentage': float, # Процент растворителя
'reagents': List[Dict] # Список реагентов с рассчитанными количествами
}
Каждый реагент в возвращаемом списке содержит:
- все исходные поля
- calculated_amount (float): рассчитанное количество реагента
- undiluted_amount (float): количество до разбавления
- amount_unit (str): единица измерения (скопирована из unit)
ПРИМЕР ИСПОЛЬЗОВАНИЯ (в CLI):
-----------------------------
>>> reagents = [
... {'name': 'Глюкоза', 'percentage': 2.0, 'unit': 'г', 'conversion_factor': 1.0},
... {'name': 'Пептон', 'percentage': 1.0, 'unit': 'г', 'conversion_factor': 1.0}
... ]
>>> result = calculate_medium_composition(1000, 'мл', reagents)
>>> print(f"Растворитель: {result['solvent_volume']} мл")
Растворитель: 970.0 мл
>>> for r in result['reagents']:
... print(f"{r['name']}: {r['calculated_amount']} {r['unit']}")
Глюкоза: 20.0 г
Пептон: 10.0 г
"""
# Проверка входных данных
if total_volume <= 0:
raise ValueError(f"Общий объём должен быть положительным: {total_volume}")
if volume_unit not in VOLUME_UNITS:
raise ValueError(f"Неизвестная единица объёма: {volume_unit}")
# Суммируем проценты всех реагентов
total_percentage = sum(r.get('percentage', 0) for r in reagents)
if total_percentage > 100:
raise ValueError(
f"Сумма процентов ({total_percentage:.2f}%) превышает 100%"
)
# Конвертируем общий объём в базовую единицу (мкл)
total_base = convert_units(total_volume, volume_unit)
results = []
total_diluted_volume_base = 0 # объём разбавленных реагентов в мкл
for reagent in reagents:
# Извлекаем параметры с значениями по умолчанию
percentage = reagent.get('percentage', 0)
unit = reagent.get('unit', 'мг')
# print ("unit = ",unit)
# conversion_factor = reagent.get('conversion_factor', 1.0)
dilution_factor = reagent.get('dilution_factor', 1.0)
# Проверяем, является ли реагент жидкостью (объём) или твёрдым веществом (масса)
is_volume = unit in VOLUME_UNITS
# 1. Объём реагента в среде (исходя из процента)
amount_in_base = (percentage / 100) * total_base
# print ("amount_in_base = ",amount_in_base)
# 2. Применяем коэффициент конверсии
# adjusted_amount_base = amount_in_base * conversion_factor
# 3. Конвертируем в нужную единицу (без учёта разбавления)
# undiluted_amount = convert_units(adjusted_amount_base, volume_unit, unit)
undiluted_amount = convert_units(amount_in_base, 'мкл', unit)
# print ("volume_unit = ",volume_unit)
# 4. Применяем разбавление
if dilution_factor <= 0:
dilution_factor = 1.0
diluted_amount = undiluted_amount * dilution_factor
# print ("diluted_amount = ", diluted_amount)
# 5. Для объёмных реагентов учитываем в расчёте растворителя
if is_volume:
reagent_volume_base = convert_units(diluted_amount, unit)
total_diluted_volume_base += reagent_volume_base
# Сохраняем результат
reagent_result = reagent.copy()
reagent_result['calculated_amount'] = diluted_amount
reagent_result['undiluted_amount'] = undiluted_amount
reagent_result['amount_unit'] = unit
results.append(reagent_result)
# Рассчитываем объём растворителя
solvent_volume_base = total_base - total_diluted_volume_base
if solvent_volume_base < 0:
solvent_volume_base = 0
solvent_volume = convert_units(solvent_volume_base, 'мкл', volume_unit)
solvent_percentage = 100 - total_percentage
return {
'total_volume': total_volume,
'total_unit': volume_unit,
'solvent_name': solvent_name,
'solvent_volume': solvent_volume,
'solvent_percentage': solvent_percentage,
'reagents': results
}