feat: инициализация проекта калькулятора питательных сред
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
import json
|
||||
|
||||
|
||||
VOLUME_UNITS = {
|
||||
'нл': 0.001, # 1 нл = 0.001 мкл
|
||||
'мкл': 1.0, # базовая единица объёма
|
||||
'мл': 1000.0, # 1 мл = 1000 мкл
|
||||
'л': 1000000.0 # 1 л = 1 000 000 мкл
|
||||
}
|
||||
|
||||
MASS_UNITS = {
|
||||
'нг': 0.000001, # 1 нг = 0.001 мкг
|
||||
'мкг': 0.001, # базовая единица массы
|
||||
'мг': 1.0, # 1 мг = 1000 мкг
|
||||
'г': 1000.0, # 1 г = 1 000 000 мкг
|
||||
'кг': 1000000.0 # 1 кг = 1 000 000 000 мкг
|
||||
}
|
||||
|
||||
class Reagent:
|
||||
def __init__(self, name: str, percentage: float, unit: str, conversion_factor: float = 1.0):
|
||||
self.name = name
|
||||
self.percentage = percentage
|
||||
self.unit = unit
|
||||
self.conversion_factor = conversion_factor
|
||||
|
||||
def to_dict(self):
|
||||
"""Преобразует реагент в словарь для сохранения в JSON"""
|
||||
return {
|
||||
'name': self.name,
|
||||
'percentage': self.percentage,
|
||||
'unit': self.unit,
|
||||
'conversion_factor': self.conversion_factor
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data):
|
||||
"""Создаёт реагент из словаря, загруженного из JSON"""
|
||||
return cls(
|
||||
name=data['name'],
|
||||
percentage=data['percentage'],
|
||||
unit=data['unit'],
|
||||
conversion_factor=data['conversion_factor']
|
||||
)
|
||||
|
||||
class Model:
|
||||
def __init__(self):
|
||||
self.reagents = []
|
||||
self.total_amount = 1000.0 # по умолчанию 1000 мл
|
||||
self.amount_unit = "мл"
|
||||
self.solvent = "Вода"
|
||||
def convert_amount(self, amount_mkl_or_mkg: float, target_unit: str, is_volume: bool) -> float:
|
||||
"""
|
||||
Пересчитывает количество из базовых единиц (мкл/мкг) в целевую единицу.
|
||||
|
||||
Args:
|
||||
amount_mkl_or_mkg: количество в базовых единицах (мкл или мкг)
|
||||
target_unit: целевая единица измерения
|
||||
is_volume: True — объём, False — масса
|
||||
|
||||
Returns:
|
||||
Количество в целевой единице
|
||||
"""
|
||||
if is_volume:
|
||||
conversion_factor = VOLUME_UNITS.get(target_unit, 1.0)
|
||||
else:
|
||||
conversion_factor = MASS_UNITS.get(target_unit, 1.0)
|
||||
|
||||
return amount_mkl_or_mkg / conversion_factor
|
||||
|
||||
def add_reagent(self, reagent: Reagent):
|
||||
"""Добавляет реагент в список"""
|
||||
self.reagents.append(reagent)
|
||||
|
||||
def calculate_amounts(self) -> list:
|
||||
"""
|
||||
Рассчитывает абсолютное количество каждого реагента с учётом единиц измерения.
|
||||
Возвращает список количеств в единицах измерения реагента.
|
||||
"""
|
||||
results = []
|
||||
for reagent in self.reagents:
|
||||
# Базовый расчёт в процентах от общего количества
|
||||
base_amount = (reagent.percentage / 100) * self.total_amount
|
||||
|
||||
# Определяем, объём или масса
|
||||
is_volume = reagent.unit in VOLUME_UNITS
|
||||
is_mass = reagent.unit in MASS_UNITS
|
||||
if is_volume:
|
||||
# Переводим общее количество среды в мкл для расчёта
|
||||
total_in_mkl = self.total_amount * VOLUME_UNITS[self.amount_unit]
|
||||
# Расчёт в мкл
|
||||
amount_in_mkl = (reagent.percentage / 100) * total_in_mkl
|
||||
# Переводим обратно в единицы реагента
|
||||
final_amount = self.convert_amount(amount_in_mkl, reagent.unit, True)
|
||||
elif is_mass:
|
||||
# Переводим общее количество среды в мкг для расчёта (если среда в единицах объёма,
|
||||
# предполагаем плотность = 1 г/мл)
|
||||
if self.amount_unit in VOLUME_UNITS:
|
||||
# Предполагаем плотность 1 г/мл: 1 мл ≈ 1 г
|
||||
total_in_mkg = self.total_amount * VOLUME_UNITS[self.amount_unit] # в мкл
|
||||
total_in_mkg *= 1000 # переводим в мкг (1 мкл воды ≈ 1 мкг)
|
||||
else:
|
||||
total_in_mkg = self.total_amount * MASS_UNITS[self.amount_unit]
|
||||
|
||||
# Расчёт в мкг
|
||||
amount_in_mkg = (reagent.percentage / 100) * total_in_mkg
|
||||
# Переводим в единицы реагента
|
||||
final_amount = self.convert_amount(amount_in_mkg, reagent.unit, False)
|
||||
else:
|
||||
# Если единица неизвестна, возвращаем базовый расчёт
|
||||
final_amount = base_amount
|
||||
|
||||
results.append(final_amount)
|
||||
return results
|
||||
|
||||
|
||||
def get_solvent_info(self) -> dict:
|
||||
"""Возвращает информацию о растворителе: процент и количество"""
|
||||
total_percentage = sum(r.percentage for r in self.reagents)
|
||||
solvent_percentage = max(0, 100 - total_percentage) # не меньше 0%
|
||||
solvent_amount = (solvent_percentage / 100) * self.total_amount
|
||||
return {
|
||||
'percentage': solvent_percentage,
|
||||
'amount': solvent_amount,
|
||||
'unit': self.amount_unit
|
||||
}
|
||||
|
||||
def save_to_file(self, filename: str):
|
||||
"""Сохраняет состав среды в JSON‑файл"""
|
||||
data = {
|
||||
'total_amount': self.total_amount,
|
||||
'amount_unit': self.amount_unit,
|
||||
'solvent': self.solvent,
|
||||
'reagents': [r.to_dict() for r in self.reagents]
|
||||
}
|
||||
with open(filename, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
|
||||
def load_from_file(self, filename: str):
|
||||
"""Загружает состав среды из JSON‑файла"""
|
||||
with open(filename, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
# Восстанавливаем данные модели
|
||||
self.total_amount = data['total_amount']
|
||||
self.amount_unit = data['amount_unit']
|
||||
self.solvent = data['solvent']
|
||||
# Очищаем и заполняем список реагентов
|
||||
self.reagents.clear()
|
||||
for reagent_data in data['reagents']:
|
||||
reagent = Reagent.from_dict(reagent_data)
|
||||
self.reagents.append(reagent)
|
||||
Reference in New Issue
Block a user