Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -14,6 +14,8 @@ from io import BytesIO
|
|
14 |
|
15 |
|
16 |
|
|
|
|
|
17 |
|
18 |
|
19 |
|
@@ -679,166 +681,154 @@ def view_image():
|
|
679 |
|
680 |
|
681 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
682 |
fertilizers_db = {
|
683 |
-
# Кальциевая селитра (Ca(NO3)2 · 4H2O - тетрагидрат)
|
684 |
"Кальциевая селитра": {
|
685 |
-
"N (NO3-)": 0.118, # 11.8%
|
686 |
-
"Ca": 0.169 # 16.9%
|
687 |
},
|
688 |
-
|
689 |
-
# Калий азотнокислый (KNO3)
|
690 |
"Калий азотнокислый": {
|
691 |
-
"N (NO3-)": 0.138, # 13.8%
|
692 |
-
"K": 0.387 # 38.7%
|
693 |
},
|
694 |
-
|
695 |
-
# Аммоний азотнокислый (NH4NO3)
|
696 |
"Аммоний азотнокислый": {
|
697 |
-
"N (NO3-)": 0.175, # 17.5%
|
698 |
-
"N (NH4+)": 0.175 # 17.5%
|
699 |
},
|
700 |
-
|
701 |
-
# Сульфат магния (MgSO4 · 7H2O - гептагидрат)
|
702 |
"Сульфат магния": {
|
703 |
-
"Mg": 0.098, # 9.8%
|
704 |
-
"S": 0.13 # 13%
|
705 |
},
|
706 |
-
|
707 |
-
# Монофосфат калия (KH2PO4)
|
708 |
"Монофосфат калия": {
|
709 |
-
"P": 0.227, # 22.7%
|
710 |
-
"K": 0.287 # 28.7%
|
711 |
}
|
712 |
}
|
713 |
|
714 |
-
class
|
715 |
def __init__(self, volume_liters=1.0):
|
716 |
-
self.volume = volume_liters
|
717 |
-
self.
|
718 |
-
|
719 |
-
def
|
720 |
-
|
721 |
-
|
722 |
-
self.
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
'
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
'
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
'K'
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
'
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
print("\n" + "="*50)
|
799 |
-
print("ТАБЛИЦА КОНЦЕНТРАЦИЙ ЭЛЕМЕНТОВ")
|
800 |
-
print("="*50)
|
801 |
-
print("{:<15} {:>15} {:>15}".format("Элемент", "Конц. (ppm)", "Конц. (мг/л)"))
|
802 |
-
print("-"*50)
|
803 |
-
for element, value in sorted(ppm.items()):
|
804 |
-
print("{:<15} {:>15.2f} {:>15.2f}".format(element, value, value))
|
805 |
-
print("="*50)
|
806 |
-
|
807 |
-
# Вывод данных по азоту
|
808 |
-
print("\n" + "="*50)
|
809 |
-
print("АНАЛИЗ АЗОТНЫХ СОЕДИНЕНИЙ")
|
810 |
-
print("="*50)
|
811 |
-
print(f"Общий азот (N): {ppm.get('N (NO3-)', 0) + ppm.get('N (NH4+)', 0):.2f} ppm")
|
812 |
-
print(f"Нитратный азот (NO3-): {ppm.get('N (NO3-)', 0):.2f} ppm")
|
813 |
-
print(f"Аммонийный азот (NH4+): {ppm.get('N (NH4+)', 0):.2f} ppm")
|
814 |
-
print("="*50)
|
815 |
-
|
816 |
-
# Вывод электропроводности
|
817 |
print("\n" + "="*50)
|
818 |
-
print("
|
819 |
print("="*50)
|
820 |
-
print(f"EC: {ec_simple:.2f} mS/cm")
|
821 |
-
print("="*50)
|
822 |
-
|
823 |
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
print(
|
841 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
842 |
|
843 |
|
844 |
|
|
|
14 |
|
15 |
|
16 |
|
17 |
+
import numpy as np
|
18 |
+
from tabulate import tabulate
|
19 |
|
20 |
|
21 |
|
|
|
681 |
|
682 |
|
683 |
|
684 |
+
|
685 |
+
# Профиль питательного раствора (ppm = мг/литр)
|
686 |
+
TOMATO_PROFILE = {
|
687 |
+
'N (NO3-)': 200,
|
688 |
+
'N (NH4+)': 20,
|
689 |
+
'P': 50,
|
690 |
+
'K': 350,
|
691 |
+
'Mg': 50,
|
692 |
+
'Ca': 200,
|
693 |
+
'S': 100
|
694 |
+
}
|
695 |
+
|
696 |
+
# База данных удобрений (монокомпоненты)
|
697 |
fertilizers_db = {
|
|
|
698 |
"Кальциевая селитра": {
|
699 |
+
"N (NO3-)": 0.118, # 11.8% N
|
700 |
+
"Ca": 0.169 # 16.9% Ca
|
701 |
},
|
|
|
|
|
702 |
"Калий азотнокислый": {
|
703 |
+
"N (NO3-)": 0.138, # 13.8% N
|
704 |
+
"K": 0.387 # 38.7% K
|
705 |
},
|
|
|
|
|
706 |
"Аммоний азотнокислый": {
|
707 |
+
"N (NO3-)": 0.175, # 17.5% N
|
708 |
+
"N (NH4+)": 0.175 # 17.5% N
|
709 |
},
|
|
|
|
|
710 |
"Сульфат магния": {
|
711 |
+
"Mg": 0.098, # 9.8% Mg
|
712 |
+
"S": 0.13 # 13% S
|
713 |
},
|
|
|
|
|
714 |
"Монофосфат калия": {
|
715 |
+
"P": 0.227, # 22.7% P
|
716 |
+
"K": 0.287 # 28.7% K
|
717 |
}
|
718 |
}
|
719 |
|
720 |
+
class NutrientCalculator:
|
721 |
def __init__(self, volume_liters=1.0):
|
722 |
+
self.volume = volume_liters # Объем раствора в литрах
|
723 |
+
self.results = {}
|
724 |
+
|
725 |
+
def calculate(self, profile):
|
726 |
+
"""Основной расчет"""
|
727 |
+
# Сначала считаем удобрения, содержащие только один нужный элемент
|
728 |
+
self._calc_single_component(profile)
|
729 |
+
# Затем комплексные удобрения
|
730 |
+
self._calc_complex(profile)
|
731 |
+
return self.results
|
732 |
+
|
733 |
+
def _calc_single_component(self, profile):
|
734 |
+
"""Расчет для простых солей"""
|
735 |
+
# Сульфат магния (Mg + S)
|
736 |
+
if 'Mg' in profile and 'S' in profile:
|
737 |
+
mg_needed = profile['Mg']
|
738 |
+
s_needed = profile['S']
|
739 |
+
|
740 |
+
# Вычисляем через Mg
|
741 |
+
mg_grams = (mg_needed * self.volume) / (fertilizers_db["Сульфат магния"]["Mg"] * 1000)
|
742 |
+
# Пересчитываем сколько S мы получим
|
743 |
+
s_from_mg = mg_grams * fertilizers_db["Сульфат магния"]["S"] * 1000 / self.volume
|
744 |
+
|
745 |
+
self.results["Сульфат магния"] = {
|
746 |
+
'граммы': round(mg_grams, 3),
|
747 |
+
'миллиграммы': int(mg_grams * 1000),
|
748 |
+
'внесет S': round(s_from_mg, 1)
|
749 |
+
}
|
750 |
+
profile['S'] -= s_from_mg
|
751 |
+
|
752 |
+
def _calc_complex(self, profile):
|
753 |
+
"""Расчет для комплексных удобрений"""
|
754 |
+
# Кальциевая селитра (Ca + NO3)
|
755 |
+
if 'Ca' in profile and 'N (NO3-)' in profile:
|
756 |
+
ca_grams = (profile['Ca'] * self.volume) / (fertilizers_db["Кальциевая селитра"]["Ca"] * 1000)
|
757 |
+
no3_from_ca = ca_grams * fertilizers_db["Кальциевая селитра"]["N (NO3-)"] * 1000 / self.volume
|
758 |
+
|
759 |
+
self.results["Кальциевая селитра"] = {
|
760 |
+
'граммы': round(ca_grams, 3),
|
761 |
+
'миллиграммы': int(ca_grams * 1000),
|
762 |
+
'внесет NO3': round(no3_from_ca, 1)
|
763 |
+
}
|
764 |
+
profile['N (NO3-)'] -= no3_from_ca
|
765 |
+
|
766 |
+
# Монофосфат калия (P + K)
|
767 |
+
if 'P' in profile and 'K' in profile:
|
768 |
+
p_grams = (profile['P'] * self.volume) / (fertilizers_db["Монофосфат калия"]["P"] * 1000)
|
769 |
+
k_from_p = p_grams * fertilizers_db["Монофосфат калия"]["K"] * 1000 / self.volume
|
770 |
+
|
771 |
+
self.results["Монофосфат калия"] = {
|
772 |
+
'граммы': round(p_grams, 3),
|
773 |
+
'миллиграммы': int(p_grams * 1000),
|
774 |
+
'внесет K': round(k_from_p, 1)
|
775 |
+
}
|
776 |
+
profile['K'] -= k_from_p
|
777 |
+
|
778 |
+
# Калий азотнокислый (K + NO3)
|
779 |
+
if 'K' in profile and profile['K'] > 0 and 'N (NO3-)' in profile:
|
780 |
+
k_grams = (profile['K'] * self.volume) / (fertilizers_db["Калий азотнокислый"]["K"] * 1000)
|
781 |
+
no3_from_k = k_grams * fertilizers_db["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
782 |
+
|
783 |
+
self.results["Калий азотнокислый"] = {
|
784 |
+
'граммы': round(k_grams, 3),
|
785 |
+
'миллиграммы': int(k_grams * 1000),
|
786 |
+
'внесет NO3': round(no3_from_k, 1)
|
787 |
+
}
|
788 |
+
profile['N (NO3-)'] -= no3_from_k
|
789 |
+
|
790 |
+
# Аммоний азотнокислый (NH4 + NO3)
|
791 |
+
if 'N (NH4+)' in profile and profile['N (NH4+)'] > 0:
|
792 |
+
nh4_grams = (profile['N (NH4+)'] * self.volume) / (fertilizers_db["Аммоний азотнокислый"]["N (NH4+)"] * 1000)
|
793 |
+
no3_from_nh4 = nh4_grams * fertilizers_db["Аммоний азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
794 |
+
|
795 |
+
self.results["Аммоний азотнокислый"] = {
|
796 |
+
'граммы': round(nh4_grams, 3),
|
797 |
+
'миллиграммы': int(nh4_grams * 1000),
|
798 |
+
'внесет NO3': round(no3_from_nh4, 1)
|
799 |
+
}
|
800 |
+
profile['N (NO3-)'] -= no3_from_nh4
|
801 |
+
|
802 |
+
def print_report(self, profile):
|
803 |
+
"""Красивый вывод результатов"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
804 |
print("\n" + "="*50)
|
805 |
+
print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
|
806 |
print("="*50)
|
|
|
|
|
|
|
807 |
|
808 |
+
print("\nЦЕЛЕВОЙ ПРОФИЛЬ (ppm):")
|
809 |
+
print(tabulate([(k, v) for k, v in profile.items()],
|
810 |
+
headers=["Элемент", "Концентрация"]))
|
811 |
+
|
812 |
+
print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
|
813 |
+
table = []
|
814 |
+
for fert, data in self.results.items():
|
815 |
+
table.append([
|
816 |
+
fert,
|
817 |
+
f"{data['граммы']:.3f} г",
|
818 |
+
f"{data['миллиграммы']} мг",
|
819 |
+
f"+{list(data.keys())[2]} {data[list(data.keys())[2]]} ppm"
|
820 |
+
])
|
821 |
+
print(tabulate(table,
|
822 |
+
headers=["Удобрение", "Граммы", "Миллиграммы", "Дополнительно"]))
|
823 |
+
|
824 |
+
print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
|
825 |
+
print(tabulate([(k, v) for k, v in profile.items() if v > 0.1],
|
826 |
+
headers=["Элемент", "Недостача (ppm)"]))
|
827 |
+
|
828 |
+
# Пример использования
|
829 |
+
calc = NutrientCalculator(volume_liters=10) # Для 10 литров раствора
|
830 |
+
results = calc.calculate(TOMATO_PROFILE.copy())
|
831 |
+
calc.print_report(TOMATO_PROFILE.copy())
|
832 |
|
833 |
|
834 |
|