Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -702,7 +702,7 @@ BASE_PROFILE = {
|
|
702 |
'N (NH4+)': 0
|
703 |
}
|
704 |
|
705 |
-
# Полная база всех удобрений (
|
706 |
ALL_FERTILIZERS = {
|
707 |
"Кальциевая селитра": {
|
708 |
"N (NO3-)": 0.118, "Ca": 0.169
|
@@ -721,6 +721,9 @@ ALL_FERTILIZERS = {
|
|
721 |
},
|
722 |
"Калий фосфорнокислый": {
|
723 |
"P": 0.228, "K": 0.287
|
|
|
|
|
|
|
724 |
}
|
725 |
}
|
726 |
|
@@ -731,28 +734,27 @@ class NutrientCalculator:
|
|
731 |
self.final_profile = BASE_PROFILE.copy()
|
732 |
self.total_ppm = sum(BASE_PROFILE.values()) + TOTAL_NITROGEN
|
733 |
self.fertilizers_db = ALL_FERTILIZERS
|
|
|
|
|
|
|
|
|
734 |
|
735 |
-
def calculate(self
|
736 |
-
# 1.
|
737 |
-
total_parts = no3_ratio + nh4_ratio
|
738 |
-
no3 = total_n * (no3_ratio / total_parts)
|
739 |
-
nh4 = total_n * (nh4_ratio / total_parts)
|
740 |
-
|
741 |
-
# Записываем азот в профиль
|
742 |
-
self.final_profile['N (NO3-)'] = no3
|
743 |
-
self.final_profile['N (NH4+)'] = nh4
|
744 |
-
|
745 |
-
# 2. Вносим удобрения в строгом порядке
|
746 |
self._apply_magnesium_sulfate()
|
747 |
self._apply_calcium_nitrate()
|
748 |
self._apply_potassium_phosphate()
|
749 |
self._apply_ammonium_nitrate()
|
750 |
self._apply_potassium_sulfate()
|
751 |
self._apply_potassium_nitrate()
|
|
|
752 |
|
753 |
-
#
|
754 |
self._adjust_negative_values()
|
755 |
|
|
|
|
|
|
|
756 |
return self.results
|
757 |
|
758 |
def _apply_fertilizer(self, fert_name, grams, additions):
|
@@ -767,6 +769,20 @@ class NutrientCalculator:
|
|
767 |
if self.final_profile[element] < 0:
|
768 |
self.final_profile[element] = 0
|
769 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
770 |
def _apply_magnesium_sulfate(self):
|
771 |
mg_need = self.final_profile['Mg']
|
772 |
if mg_need <= 0:
|
@@ -789,7 +805,6 @@ class NutrientCalculator:
|
|
789 |
grams = (ca_need * self.volume) / (ca_content * 1000)
|
790 |
added_n = grams * self.fertilizers_db["Кальциевая селитра"]["N (NO3-)"] * 1000 / self.volume
|
791 |
|
792 |
-
self.final_profile['N (NO3-)'] -= added_n
|
793 |
self._apply_fertilizer("Кальциевая селитра", grams, {'внесет NO3': round(added_n, 1)})
|
794 |
self.final_profile['Ca'] = 0
|
795 |
|
@@ -807,7 +822,7 @@ class NutrientCalculator:
|
|
807 |
self.final_profile['P'] = 0
|
808 |
|
809 |
def _apply_ammonium_nitrate(self):
|
810 |
-
nh4_need = self.
|
811 |
if nh4_need <= 0:
|
812 |
return
|
813 |
|
@@ -815,9 +830,10 @@ class NutrientCalculator:
|
|
815 |
grams = (nh4_need * self.volume) / (nh4_content * 1000)
|
816 |
added_n = grams * self.fertilizers_db["Аммоний азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
817 |
|
818 |
-
self.
|
819 |
-
|
820 |
-
|
|
|
821 |
|
822 |
def _apply_potassium_sulfate(self):
|
823 |
k_need = self.final_profile['K']
|
@@ -829,10 +845,10 @@ class NutrientCalculator:
|
|
829 |
k_content = self.fertilizers_db["Калий сернокислый"]["K"]
|
830 |
s_content = self.fertilizers_db["Калий сернокислый"]["S"]
|
831 |
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
|
837 |
added_k = grams * k_content * 1000 / self.volume
|
838 |
added_s = grams * s_content * 1000 / self.volume
|
@@ -854,18 +870,38 @@ class NutrientCalculator:
|
|
854 |
added_n = grams * self.fertilizers_db["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
855 |
|
856 |
self.final_profile['K'] = 0
|
857 |
-
self.final_profile['N (NO3-)'] -= added_n
|
858 |
self._apply_fertilizer("Калий азотнокислый", grams, {'внесет NO3': round(added_n, 2)})
|
859 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
860 |
def calculate_ec(self):
|
861 |
return round(self.total_ppm / 700, 2)
|
862 |
|
863 |
def print_report(self):
|
864 |
print("\n" + "="*60)
|
865 |
-
print("ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА (
|
866 |
print("="*60)
|
867 |
table = [[el, round(val, 1)] for el, val in self.final_profile.items()]
|
868 |
-
print(tabulate(table, headers=["Элемент", "
|
|
|
|
|
|
|
|
|
869 |
|
870 |
print("\n" + "="*60)
|
871 |
print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
|
@@ -893,10 +929,9 @@ class NutrientCalculator:
|
|
893 |
else:
|
894 |
print(" Все элементы покрыты полностью")
|
895 |
|
896 |
-
# Пример использования
|
897 |
if __name__ == "__main__":
|
898 |
calculator = NutrientCalculator(volume_liters=10)
|
899 |
-
calculator.calculate(
|
900 |
calculator.print_report()
|
901 |
|
902 |
|
|
|
702 |
'N (NH4+)': 0
|
703 |
}
|
704 |
|
705 |
+
# Полная база всех удобрений (7 удобрений)
|
706 |
ALL_FERTILIZERS = {
|
707 |
"Кальциевая селитра": {
|
708 |
"N (NO3-)": 0.118, "Ca": 0.169
|
|
|
721 |
},
|
722 |
"Калий фосфорнокислый": {
|
723 |
"P": 0.228, "K": 0.287
|
724 |
+
},
|
725 |
+
"Монофосфат калия": {
|
726 |
+
"P": 0.228, "K": 0.287
|
727 |
}
|
728 |
}
|
729 |
|
|
|
734 |
self.final_profile = BASE_PROFILE.copy()
|
735 |
self.total_ppm = sum(BASE_PROFILE.values()) + TOTAL_NITROGEN
|
736 |
self.fertilizers_db = ALL_FERTILIZERS
|
737 |
+
self.target_nitrogen = {
|
738 |
+
'NO3': TOTAL_NITROGEN * (NO3_RATIO / (NO3_RATIO + NH4_RATIO)),
|
739 |
+
'NH4': TOTAL_NITROGEN * (NH4_RATIO / (NO3_RATIO + NH4_RATIO))
|
740 |
+
}
|
741 |
|
742 |
+
def calculate(self):
|
743 |
+
# 1. Вносим удобрения в строгом порядке
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
744 |
self._apply_magnesium_sulfate()
|
745 |
self._apply_calcium_nitrate()
|
746 |
self._apply_potassium_phosphate()
|
747 |
self._apply_ammonium_nitrate()
|
748 |
self._apply_potassium_sulfate()
|
749 |
self._apply_potassium_nitrate()
|
750 |
+
self._apply_monopotassium_phosphate()
|
751 |
|
752 |
+
# 2. Корректируем отрицательные значения
|
753 |
self._adjust_negative_values()
|
754 |
|
755 |
+
# 3. Пересчитываем фактическое содержание азота
|
756 |
+
self._recalculate_actual_nitrogen()
|
757 |
+
|
758 |
return self.results
|
759 |
|
760 |
def _apply_fertilizer(self, fert_name, grams, additions):
|
|
|
769 |
if self.final_profile[element] < 0:
|
770 |
self.final_profile[element] = 0
|
771 |
|
772 |
+
def _recalculate_actual_nitrogen(self):
|
773 |
+
# Пересчитываем фактическое содержание азота на основе внесенных удобрений
|
774 |
+
no3_added = 0
|
775 |
+
nh4_added = 0
|
776 |
+
|
777 |
+
for fert in self.results.values():
|
778 |
+
if 'внесет NO3' in fert:
|
779 |
+
no3_added += fert['внесет NO3']
|
780 |
+
if 'внесет NH4' in fert:
|
781 |
+
nh4_added += fert['внесет NH4']
|
782 |
+
|
783 |
+
self.final_profile['N (NO3-)'] = no3_added
|
784 |
+
self.final_profile['N (NH4+)'] = nh4_added
|
785 |
+
|
786 |
def _apply_magnesium_sulfate(self):
|
787 |
mg_need = self.final_profile['Mg']
|
788 |
if mg_need <= 0:
|
|
|
805 |
grams = (ca_need * self.volume) / (ca_content * 1000)
|
806 |
added_n = grams * self.fertilizers_db["Кальциевая селитра"]["N (NO3-)"] * 1000 / self.volume
|
807 |
|
|
|
808 |
self._apply_fertilizer("Кальциевая селитра", grams, {'внесет NO3': round(added_n, 1)})
|
809 |
self.final_profile['Ca'] = 0
|
810 |
|
|
|
822 |
self.final_profile['P'] = 0
|
823 |
|
824 |
def _apply_ammonium_nitrate(self):
|
825 |
+
nh4_need = self.target_nitrogen['NH4']
|
826 |
if nh4_need <= 0:
|
827 |
return
|
828 |
|
|
|
830 |
grams = (nh4_need * self.volume) / (nh4_content * 1000)
|
831 |
added_n = grams * self.fertilizers_db["Аммоний азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
832 |
|
833 |
+
self._apply_fertilizer("Аммоний азотнокислый", grams, {
|
834 |
+
'внесет NO3': round(added_n, 1),
|
835 |
+
'внесет NH4': round(nh4_need, 1)
|
836 |
+
})
|
837 |
|
838 |
def _apply_potassium_sulfate(self):
|
839 |
k_need = self.final_profile['K']
|
|
|
845 |
k_content = self.fertilizers_db["Калий сернокислый"]["K"]
|
846 |
s_content = self.fertilizers_db["Калий сернокислый"]["S"]
|
847 |
|
848 |
+
grams = min(
|
849 |
+
(k_need * self.volume) / (k_content * 1000),
|
850 |
+
(s_need * self.volume) / (s_content * 1000)
|
851 |
+
)
|
852 |
|
853 |
added_k = grams * k_content * 1000 / self.volume
|
854 |
added_s = grams * s_content * 1000 / self.volume
|
|
|
870 |
added_n = grams * self.fertilizers_db["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
|
871 |
|
872 |
self.final_profile['K'] = 0
|
|
|
873 |
self._apply_fertilizer("Калий азотнокислый", grams, {'внесет NO3': round(added_n, 2)})
|
874 |
|
875 |
+
def _apply_monopotassium_phosphate(self):
|
876 |
+
# Добавляем дополнительное фосфорное удобрение для полного покрытия
|
877 |
+
p_need = self.final_profile['P']
|
878 |
+
if p_need <= 0:
|
879 |
+
return
|
880 |
+
|
881 |
+
p_content = self.fertilizers_db["Монофосфат калия"]["P"]
|
882 |
+
grams = (p_need * self.volume) / (p_content * 1000)
|
883 |
+
added_k = grams * self.fertilizers_db["Монофосфат калия"]["K"] * 1000 / self.volume
|
884 |
+
|
885 |
+
self.final_profile['K'] -= added_k
|
886 |
+
self._apply_fertilizer("Монофосфат калия", grams, {
|
887 |
+
'внесет P': round(p_need, 1),
|
888 |
+
'внесет K': round(added_k, 1)
|
889 |
+
})
|
890 |
+
self.final_profile['P'] = 0
|
891 |
+
|
892 |
def calculate_ec(self):
|
893 |
return round(self.total_ppm / 700, 2)
|
894 |
|
895 |
def print_report(self):
|
896 |
print("\n" + "="*60)
|
897 |
+
print("ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА (ПЕРЕСЧИТАННЫЙ):")
|
898 |
print("="*60)
|
899 |
table = [[el, round(val, 1)] for el, val in self.final_profile.items()]
|
900 |
+
print(tabulate(table, headers=["Элемент", "ppm"]))
|
901 |
+
|
902 |
+
print("\nЦелевые значения азота:")
|
903 |
+
print(f" N (NO3-): {round(self.target_nitrogen['NO3'], 1)} ppm")
|
904 |
+
print(f" N (NH4+): {round(self.target_nitrogen['NH4'], 1)} ppm")
|
905 |
|
906 |
print("\n" + "="*60)
|
907 |
print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
|
|
|
929 |
else:
|
930 |
print(" Все элементы покрыты полностью")
|
931 |
|
|
|
932 |
if __name__ == "__main__":
|
933 |
calculator = NutrientCalculator(volume_liters=10)
|
934 |
+
calculator.calculate()
|
935 |
calculator.print_report()
|
936 |
|
937 |
|