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