Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -683,12 +683,12 @@ def view_image():
|
|
683 |
|
684 |
|
685 |
|
686 |
-
|
|
|
|
|
687 |
|
688 |
# Профиль питательного раствора для томатов (ppm)
|
689 |
TOMATO_PROFILE = {
|
690 |
-
'N (NO3-)': 200,
|
691 |
-
'N (NH4+)': 20,
|
692 |
'P': 50,
|
693 |
'K': 350,
|
694 |
'Mg': 50,
|
@@ -696,7 +696,7 @@ TOMATO_PROFILE = {
|
|
696 |
'S': 100
|
697 |
}
|
698 |
|
699 |
-
#
|
700 |
fertilizers_db = {
|
701 |
"Кальциевая селитра": {
|
702 |
"N (NO3-)": 0.118,
|
@@ -706,9 +706,9 @@ fertilizers_db = {
|
|
706 |
"N (NO3-)": 0.138,
|
707 |
"K": 0.387,
|
708 |
},
|
709 |
-
"Калий сернокислый": {
|
710 |
-
"K": 0.448,
|
711 |
-
"S": 0.184,
|
712 |
},
|
713 |
"Аммоний азотнокислый": {
|
714 |
"N (NO3-)": 0.175,
|
@@ -724,19 +724,31 @@ fertilizers_db = {
|
|
724 |
}
|
725 |
}
|
726 |
|
|
|
727 |
class NutrientCalculator:
|
728 |
def __init__(self, volume_liters=1.0):
|
729 |
self.volume = volume_liters
|
730 |
self.results = {}
|
731 |
self.final_profile = {}
|
732 |
-
self.total_ppm =
|
|
|
|
|
|
|
|
|
|
|
|
|
733 |
|
734 |
-
|
735 |
-
self.final_profile =
|
|
|
|
|
|
|
|
|
|
|
736 |
self._apply_magnesium_sulfate()
|
737 |
self._apply_calcium_nitrate()
|
738 |
self._apply_mkp()
|
739 |
-
self._apply_potassium_fertilizers()
|
740 |
self._apply_ammonium_nitrate()
|
741 |
return self.results
|
742 |
|
@@ -778,51 +790,36 @@ class NutrientCalculator:
|
|
778 |
self.final_profile['P'] = 0
|
779 |
|
780 |
def _apply_potassium_fertilizers(self):
|
781 |
-
"""Новый метод для распределения калия между двумя удобрениями"""
|
782 |
k_need = self.final_profile['K']
|
783 |
if k_need <= 0:
|
784 |
return
|
785 |
-
|
786 |
-
# Сначала вносим часть калия через сернокислый калий для компенсации серы
|
787 |
s_deficit = max(0, self.final_profile['S'])
|
788 |
if s_deficit > 0:
|
789 |
-
# Рассчитываем сколько сернокислого калия нужно для компенсации дефицита серы
|
790 |
s_content = fertilizers_db["Калий сернокислый"]["S"]
|
791 |
k2so4_grams = (s_deficit * self.volume) / (s_content * 1000)
|
792 |
-
|
793 |
-
# Сколько калия это добавит
|
794 |
added_k = k2so4_grams * fertilizers_db["Калий сернокислый"]["K"] * 1000 / self.volume
|
795 |
-
|
796 |
-
# Если этим удобрением мы покрываем больше калия, чем нужно
|
797 |
if added_k > k_need:
|
798 |
k2so4_grams = (k_need * self.volume) / (fertilizers_db["Калий сернокислый"]["K"] * 1000)
|
799 |
added_k = k_need
|
800 |
added_s = k2so4_grams * fertilizers_db["Калий сернокислый"]["S"] * 1000 / self.volume
|
801 |
else:
|
802 |
added_s = s_deficit
|
803 |
-
|
804 |
-
self._apply_fertilizer(
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
'внесет K': round(added_k, 1),
|
809 |
-
'внесет S': round(added_s, 1)
|
810 |
-
}
|
811 |
-
)
|
812 |
self.final_profile['K'] -= added_k
|
813 |
self.final_profile['S'] -= added_s
|
814 |
k_need = self.final_profile['K']
|
815 |
-
|
816 |
-
# Остаток калия вносим азотнокислым калием
|
817 |
if k_need > 0:
|
818 |
kno3_grams = (k_need * self.volume) / (fertilizers_db["Калий азотнокислый"]["K"] * 1000)
|
819 |
added_n = kno3_grams * fertilizers_db["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
820 |
-
|
821 |
-
self._apply_fertilizer(
|
822 |
-
"Калий азотнокислый",
|
823 |
-
kno3_grams,
|
824 |
-
{'внесет NO3': round(added_n, 1)}
|
825 |
-
)
|
826 |
self.final_profile['K'] = 0
|
827 |
self.final_profile['N (NO3-)'] -= added_n
|
828 |
|
@@ -839,29 +836,24 @@ class NutrientCalculator:
|
|
839 |
self.final_profile['N (NH4+)'] = 0
|
840 |
|
841 |
def calculate_ec(self):
|
842 |
-
"""Расчет электропроводимости (700 ppm ≈ 1 mS/cm)"""
|
843 |
return round(self.total_ppm / 700, 2)
|
844 |
|
845 |
def print_report(self):
|
846 |
-
# Сначала выводим заданный профиль
|
847 |
print("\n" + "="*50)
|
848 |
print("ЗАДАННЫЙ ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА (ppm):")
|
849 |
print("="*50)
|
850 |
profile_table = []
|
851 |
-
for element, value in
|
852 |
-
profile_table.append([element, value])
|
853 |
print(tabulate(profile_table, headers=["Элемент", "Концентрация (ppm)"]))
|
854 |
-
|
855 |
-
# Затем выводим результаты расчета
|
856 |
ec = self.calculate_ec()
|
857 |
-
|
858 |
print("\n" + "="*50)
|
859 |
print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
|
860 |
print("="*50)
|
861 |
-
|
862 |
print(f"\nОБЩАЯ КОНЦЕНТРАЦИЯ: {self.total_ppm} ppm")
|
863 |
print(f"ЭЛЕКТРОПРОВОДИМОСТЬ (EC): {ec} mS/cm (при 25°C)")
|
864 |
-
|
865 |
print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
|
866 |
table = []
|
867 |
for fert, data in self.results.items():
|
@@ -873,7 +865,7 @@ class NutrientCalculator:
|
|
873 |
"\n".join(additions)
|
874 |
])
|
875 |
print(tabulate(table, headers=["Удобрение", "Граммы", "Миллиграммы", "Добавит"]))
|
876 |
-
|
877 |
print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
|
878 |
deficit = {k: v for k, v in self.final_profile.items() if v > 0.1}
|
879 |
if deficit:
|
@@ -882,10 +874,11 @@ class NutrientCalculator:
|
|
882 |
else:
|
883 |
print(" Все элементы полностью покрыты")
|
884 |
|
|
|
885 |
# Пример использования
|
886 |
if __name__ == "__main__":
|
887 |
calc = NutrientCalculator(volume_liters=10)
|
888 |
-
results = calc.calculate(TOMATO_PROFILE.copy())
|
889 |
calc.print_report()
|
890 |
|
891 |
|
@@ -897,7 +890,5 @@ if __name__ == "__main__":
|
|
897 |
|
898 |
|
899 |
|
900 |
-
|
901 |
-
|
902 |
if __name__ == '__main__':
|
903 |
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))
|
|
|
683 |
|
684 |
|
685 |
|
686 |
+
# Общий азот и соотношение NO3:NH4
|
687 |
+
TOTAL_NITROGEN = 220 # ppm
|
688 |
+
N_RATIO = (10, 1) # Пример: 10:1 (NO3:NH4)
|
689 |
|
690 |
# Профиль питательного раствора для томатов (ppm)
|
691 |
TOMATO_PROFILE = {
|
|
|
|
|
692 |
'P': 50,
|
693 |
'K': 350,
|
694 |
'Mg': 50,
|
|
|
696 |
'S': 100
|
697 |
}
|
698 |
|
699 |
+
# База данных удобрений
|
700 |
fertilizers_db = {
|
701 |
"Кальциевая селитра": {
|
702 |
"N (NO3-)": 0.118,
|
|
|
706 |
"N (NO3-)": 0.138,
|
707 |
"K": 0.387,
|
708 |
},
|
709 |
+
"Калий сернокислый": {
|
710 |
+
"K": 0.448,
|
711 |
+
"S": 0.184,
|
712 |
},
|
713 |
"Аммоний азотнокислый": {
|
714 |
"N (NO3-)": 0.175,
|
|
|
724 |
}
|
725 |
}
|
726 |
|
727 |
+
|
728 |
class NutrientCalculator:
|
729 |
def __init__(self, volume_liters=1.0):
|
730 |
self.volume = volume_liters
|
731 |
self.results = {}
|
732 |
self.final_profile = {}
|
733 |
+
self.total_ppm = 0
|
734 |
+
|
735 |
+
def calculate(self, base_profile, total_n, n_ratio):
|
736 |
+
# Расчёт NO3 и NH4 на основе общего азота и соотношения
|
737 |
+
total_parts = n_ratio[0] + n_ratio[1]
|
738 |
+
no3 = total_n * (n_ratio[0] / total_parts)
|
739 |
+
nh4 = total_n * (n_ratio[1] / total_parts)
|
740 |
|
741 |
+
# Формирование полного профиля
|
742 |
+
self.final_profile = base_profile.copy()
|
743 |
+
self.final_profile['N (NO3-)'] = no3
|
744 |
+
self.final_profile['N (NH4+)'] = nh4
|
745 |
+
self.total_ppm = total_n + sum(base_profile.values())
|
746 |
+
|
747 |
+
# Последовательное внесение удобрений
|
748 |
self._apply_magnesium_sulfate()
|
749 |
self._apply_calcium_nitrate()
|
750 |
self._apply_mkp()
|
751 |
+
self._apply_potassium_fertilizers()
|
752 |
self._apply_ammonium_nitrate()
|
753 |
return self.results
|
754 |
|
|
|
790 |
self.final_profile['P'] = 0
|
791 |
|
792 |
def _apply_potassium_fertilizers(self):
|
|
|
793 |
k_need = self.final_profile['K']
|
794 |
if k_need <= 0:
|
795 |
return
|
796 |
+
|
|
|
797 |
s_deficit = max(0, self.final_profile['S'])
|
798 |
if s_deficit > 0:
|
|
|
799 |
s_content = fertilizers_db["Калий сернокислый"]["S"]
|
800 |
k2so4_grams = (s_deficit * self.volume) / (s_content * 1000)
|
|
|
|
|
801 |
added_k = k2so4_grams * fertilizers_db["Калий сернокислый"]["K"] * 1000 / self.volume
|
802 |
+
|
|
|
803 |
if added_k > k_need:
|
804 |
k2so4_grams = (k_need * self.volume) / (fertilizers_db["Калий сернокислый"]["K"] * 1000)
|
805 |
added_k = k_need
|
806 |
added_s = k2so4_grams * fertilizers_db["Калий сернокислый"]["S"] * 1000 / self.volume
|
807 |
else:
|
808 |
added_s = s_deficit
|
809 |
+
|
810 |
+
self._apply_fertilizer("Калий сернокислый", k2so4_grams, {
|
811 |
+
'внесет K': round(added_k, 1),
|
812 |
+
'внесет S': round(added_s, 1)
|
813 |
+
})
|
|
|
|
|
|
|
|
|
814 |
self.final_profile['K'] -= added_k
|
815 |
self.final_profile['S'] -= added_s
|
816 |
k_need = self.final_profile['K']
|
817 |
+
|
|
|
818 |
if k_need > 0:
|
819 |
kno3_grams = (k_need * self.volume) / (fertilizers_db["Калий азотнокислый"]["K"] * 1000)
|
820 |
added_n = kno3_grams * fertilizers_db["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
821 |
+
|
822 |
+
self._apply_fertilizer("Калий азотнокислый", kno3_grams, {'внесет NO3': round(added_n, 1)})
|
|
|
|
|
|
|
|
|
823 |
self.final_profile['K'] = 0
|
824 |
self.final_profile['N (NO3-)'] -= added_n
|
825 |
|
|
|
836 |
self.final_profile['N (NH4+)'] = 0
|
837 |
|
838 |
def calculate_ec(self):
|
|
|
839 |
return round(self.total_ppm / 700, 2)
|
840 |
|
841 |
def print_report(self):
|
|
|
842 |
print("\n" + "="*50)
|
843 |
print("ЗАДАННЫЙ ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА (ppm):")
|
844 |
print("="*50)
|
845 |
profile_table = []
|
846 |
+
for element, value in self.final_profile.items():
|
847 |
+
profile_table.append([element, round(value, 1)])
|
848 |
print(tabulate(profile_table, headers=["Элемент", "Концентрация (ppm)"]))
|
849 |
+
|
|
|
850 |
ec = self.calculate_ec()
|
|
|
851 |
print("\n" + "="*50)
|
852 |
print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
|
853 |
print("="*50)
|
|
|
854 |
print(f"\nОБЩАЯ КОНЦЕНТРАЦИЯ: {self.total_ppm} ppm")
|
855 |
print(f"ЭЛЕКТРОПРОВОДИМОСТЬ (EC): {ec} mS/cm (при 25°C)")
|
856 |
+
|
857 |
print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
|
858 |
table = []
|
859 |
for fert, data in self.results.items():
|
|
|
865 |
"\n".join(additions)
|
866 |
])
|
867 |
print(tabulate(table, headers=["Удобрение", "Граммы", "Миллиграммы", "Добавит"]))
|
868 |
+
|
869 |
print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
|
870 |
deficit = {k: v for k, v in self.final_profile.items() if v > 0.1}
|
871 |
if deficit:
|
|
|
874 |
else:
|
875 |
print(" Все элементы полностью покрыты")
|
876 |
|
877 |
+
|
878 |
# Пример использования
|
879 |
if __name__ == "__main__":
|
880 |
calc = NutrientCalculator(volume_liters=10)
|
881 |
+
results = calc.calculate(TOMATO_PROFILE.copy(), total_n=TOTAL_NITROGEN, n_ratio=N_RATIO)
|
882 |
calc.print_report()
|
883 |
|
884 |
|
|
|
890 |
|
891 |
|
892 |
|
|
|
|
|
893 |
if __name__ == '__main__':
|
894 |
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))
|