Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -715,11 +715,16 @@ class NutrientCalculator:
|
|
715 |
self.profile = BASE_PROFILE.copy()
|
716 |
self.total_ppm = sum(BASE_PROFILE.values()) + TOTAL_NITROGEN
|
717 |
self.fertilizers = FERTILIZERS
|
|
|
718 |
|
719 |
# Рассчитываем целевые значения азота
|
720 |
total_parts = NO3_RATIO + NH4_RATIO
|
721 |
self.target_no3 = TOTAL_NITROGEN * (NO3_RATIO / total_parts)
|
722 |
self.target_nh4 = TOTAL_NITROGEN * (NH4_RATIO / total_parts)
|
|
|
|
|
|
|
|
|
723 |
|
724 |
def calculate(self):
|
725 |
# 1. Вносим сульфат магния (Mg)
|
@@ -743,6 +748,9 @@ class NutrientCalculator:
|
|
743 |
# Пересчитываем фактическое содержание азота
|
744 |
self._recalculate_nitrogen()
|
745 |
|
|
|
|
|
|
|
746 |
return self.results
|
747 |
|
748 |
def _apply_fertilizer(self, name, ppm_needed, main_element, additions):
|
@@ -753,12 +761,18 @@ class NutrientCalculator:
|
|
753 |
for element, label in additions.items():
|
754 |
added_amount = grams * self.fertilizers[name][element] * 1000 / self.volume
|
755 |
added[label] = round(added_amount, 1)
|
|
|
|
|
|
|
756 |
|
757 |
self.results[name] = {
|
758 |
'граммы': round(grams, 3),
|
759 |
'миллиграммы': int(grams * 1000),
|
760 |
**added
|
761 |
}
|
|
|
|
|
|
|
762 |
|
763 |
def _apply_potassium_sulfate(self):
|
764 |
# Рассчитываем необходимое количество для покрытия дефицита
|
@@ -779,6 +793,10 @@ class NutrientCalculator:
|
|
779 |
'внесет K': round(added_k, 1),
|
780 |
'внесет S': round(added_s, 1)
|
781 |
}
|
|
|
|
|
|
|
|
|
782 |
|
783 |
def _apply_potassium_nitrate(self):
|
784 |
# Рассчитываем остаточную потребность в калии
|
@@ -795,6 +813,10 @@ class NutrientCalculator:
|
|
795 |
'внесет K': round(added_k, 1),
|
796 |
'внесет NO3': round(added_n, 1)
|
797 |
}
|
|
|
|
|
|
|
|
|
798 |
|
799 |
def _recalculate_nitrogen(self):
|
800 |
# Суммируем весь внесенный азот
|
@@ -805,30 +827,41 @@ class NutrientCalculator:
|
|
805 |
self.profile['N (NO3-)'] = total_no3
|
806 |
self.profile['N (NH4+)'] = total_nh4
|
807 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
808 |
def calculate_ec(self):
|
809 |
return round(self.total_ppm / 700, 2)
|
810 |
|
811 |
def print_report(self):
|
812 |
print("\n" + "="*60)
|
813 |
-
print("ПРОФИЛЬ ПИТАТЕЛЬНОГО
|
814 |
print("="*60)
|
815 |
-
|
816 |
-
# Выводим базовые значения + пересчитанный азот
|
817 |
-
profile_to_show = BASE_PROFILE.copy()
|
818 |
-
profile_to_show['N (NO3-)'] = self.profile['N (NO3-)']
|
819 |
-
profile_to_show['N (NH4+)'] = self.profile['N (NH4+)']
|
820 |
-
|
821 |
-
table = [[el, round(val, 1)] for el, val in profile_to_show.items()]
|
822 |
print(tabulate(table, headers=["Элемент", "ppm"]))
|
823 |
-
|
|
|
|
|
|
|
|
|
824 |
print("\n" + "="*60)
|
825 |
print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
|
826 |
print("="*60)
|
827 |
print(f"Общая концентрация: {round(self.total_ppm, 1)} ppm")
|
828 |
print(f"EC: {self.calculate_ec()} mS/cm")
|
829 |
-
print(f"Общий а��от: {TOTAL_NITROGEN} ppm (NO3-: {round(self.target_no3,1)} ppm, NH4+: {round(self.target_nh4,1)} ppm)")
|
830 |
|
831 |
-
print("\nРЕКОМЕНДУЕМЫЕ
|
832 |
fert_table = []
|
833 |
for fert, data in self.results.items():
|
834 |
details = [f"+{k}: {v} ppm" for k, v in data.items() if k.startswith('внесет')]
|
@@ -840,6 +873,14 @@ class NutrientCalculator:
|
|
840 |
])
|
841 |
print(tabulate(fert_table, headers=["Удобрение", "Граммы", "Миллиграммы", "Добавит"]))
|
842 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
843 |
if __name__ == "__main__":
|
844 |
calculator = NutrientCalculator(volume_liters=VOLUME_LITERS)
|
845 |
calculator.calculate()
|
|
|
715 |
self.profile = BASE_PROFILE.copy()
|
716 |
self.total_ppm = sum(BASE_PROFILE.values()) + TOTAL_NITROGEN
|
717 |
self.fertilizers = FERTILIZERS
|
718 |
+
self.final_profile = BASE_PROFILE.copy()
|
719 |
|
720 |
# Рассчитываем целевые значения азота
|
721 |
total_parts = NO3_RATIO + NH4_RATIO
|
722 |
self.target_no3 = TOTAL_NITROGEN * (NO3_RATIO / total_parts)
|
723 |
self.target_nh4 = TOTAL_NITROGEN * (NH4_RATIO / total_parts)
|
724 |
+
self.initial_n_profile = {
|
725 |
+
"NO3-": self.target_no3,
|
726 |
+
"NH4+": self.target_nh4
|
727 |
+
}
|
728 |
|
729 |
def calculate(self):
|
730 |
# 1. Вносим сульфат магния (Mg)
|
|
|
748 |
# Пересчитываем фактическое содержание азота
|
749 |
self._recalculate_nitrogen()
|
750 |
|
751 |
+
# Обновляем финальный профиль
|
752 |
+
self._update_final_profile()
|
753 |
+
|
754 |
return self.results
|
755 |
|
756 |
def _apply_fertilizer(self, name, ppm_needed, main_element, additions):
|
|
|
761 |
for element, label in additions.items():
|
762 |
added_amount = grams * self.fertilizers[name][element] * 1000 / self.volume
|
763 |
added[label] = round(added_amount, 1)
|
764 |
+
# Уменьшаем дефицит по этому элементу
|
765 |
+
if element in self.final_profile:
|
766 |
+
self.final_profile[element] -= added_amount
|
767 |
|
768 |
self.results[name] = {
|
769 |
'граммы': round(grams, 3),
|
770 |
'миллиграммы': int(grams * 1000),
|
771 |
**added
|
772 |
}
|
773 |
+
|
774 |
+
# Уменьшаем дефицит по основному элементу
|
775 |
+
self.final_profile[main_element] -= ppm_needed
|
776 |
|
777 |
def _apply_potassium_sulfate(self):
|
778 |
# Рассчитываем необходимое количество для покрытия дефицита
|
|
|
793 |
'внесет K': round(added_k, 1),
|
794 |
'внесет S': round(added_s, 1)
|
795 |
}
|
796 |
+
|
797 |
+
# Обновляем финальный профиль
|
798 |
+
self.final_profile['K'] -= added_k
|
799 |
+
self.final_profile['S'] -= added_s
|
800 |
|
801 |
def _apply_potassium_nitrate(self):
|
802 |
# Рассчитываем остаточную потребность в калии
|
|
|
813 |
'внесет K': round(added_k, 1),
|
814 |
'внесет NO3': round(added_n, 1)
|
815 |
}
|
816 |
+
|
817 |
+
# Обновляем финальный профиль
|
818 |
+
self.final_profile['K'] -= added_k
|
819 |
+
self.final_profile['N (NO3-)'] += added_n
|
820 |
|
821 |
def _recalculate_nitrogen(self):
|
822 |
# Суммируем весь внесенный азот
|
|
|
827 |
self.profile['N (NO3-)'] = total_no3
|
828 |
self.profile['N (NH4+)'] = total_nh4
|
829 |
|
830 |
+
def _update_final_profile(self):
|
831 |
+
# Обновляем финальный профиль с учетом внесенных элементов
|
832 |
+
for fert, data in self.results.items():
|
833 |
+
for key, value in data.items():
|
834 |
+
if key.startswith('внесет'):
|
835 |
+
element = key.split(': ')[0].replace('внесет ', '')
|
836 |
+
if element == 'NO3':
|
837 |
+
element = 'N (NO3-)'
|
838 |
+
elif element == 'NH4':
|
839 |
+
element = 'N (NH4+)'
|
840 |
+
|
841 |
+
if element in self.final_profile:
|
842 |
+
self.final_profile[element] -= value
|
843 |
+
|
844 |
def calculate_ec(self):
|
845 |
return round(self.total_ppm / 700, 2)
|
846 |
|
847 |
def print_report(self):
|
848 |
print("\n" + "="*60)
|
849 |
+
print("ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА (ИТОГО):")
|
850 |
print("="*60)
|
851 |
+
table = [[el, round(val, 1)] for el, val in self.profile.items()]
|
|
|
|
|
|
|
|
|
|
|
|
|
852 |
print(tabulate(table, headers=["Элемент", "ppm"]))
|
853 |
+
|
854 |
+
print("\nИсходный расчёт азота:")
|
855 |
+
for form, value in self.initial_n_profile.items():
|
856 |
+
print(f" {form}: {value} ppm")
|
857 |
+
|
858 |
print("\n" + "="*60)
|
859 |
print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
|
860 |
print("="*60)
|
861 |
print(f"Общая концентрация: {round(self.total_ppm, 1)} ppm")
|
862 |
print(f"EC: {self.calculate_ec()} mS/cm")
|
|
|
863 |
|
864 |
+
print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
|
865 |
fert_table = []
|
866 |
for fert, data in self.results.items():
|
867 |
details = [f"+{k}: {v} ppm" for k, v in data.items() if k.startswith('внесет')]
|
|
|
873 |
])
|
874 |
print(tabulate(fert_table, headers=["Удобрение", "Граммы", "Миллиграммы", "Добавит"]))
|
875 |
|
876 |
+
print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
|
877 |
+
deficit = {k: round(abs(v), 1) for k, v in self.final_profile.items() if abs(v) > 0.1}
|
878 |
+
if deficit:
|
879 |
+
for el, val in deficit.items():
|
880 |
+
print(f" {el}: {val} ppm")
|
881 |
+
else:
|
882 |
+
print(" Все элементы покрыты полностью")
|
883 |
+
|
884 |
if __name__ == "__main__":
|
885 |
calculator = NutrientCalculator(volume_liters=VOLUME_LITERS)
|
886 |
calculator.calculate()
|