DmitrMakeev commited on
Commit
953680e
·
verified ·
1 Parent(s): 1433d75

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -64
app.py CHANGED
@@ -685,7 +685,6 @@ def nutri_call():
685
 
686
 
687
 
688
-
689
  from tabulate import tabulate
690
 
691
  # Константы
@@ -696,8 +695,8 @@ VOLUME_LITERS = 100
696
 
697
  # Коэффициенты электропроводности
698
  EC_COEFFICIENTS = {
699
- 'P': 0.0012, 'K': 0.0018, 'Mg': 0.0015,
700
- 'Ca': 0.0016, 'S': 0.0014,
701
  'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
702
  }
703
 
@@ -723,13 +722,18 @@ class NutrientCalculator:
723
  self.results = {}
724
  self.target_profile = BASE_PROFILE.copy()
725
  self.actual_profile = {k: 0.0 for k in BASE_PROFILE}
726
- self.fertilizers = NUTRIENT_CONTENT_IN_FERTILIZERS
727
  self.total_ec = 0.0
 
 
 
 
 
728
 
729
  # Расчёт азота
730
- total_parts = NO3_RATIO + NH4_RATIO
731
- self.target_profile['N (NO3-)'] = TOTAL_NITROGEN * (NO3_RATIO / total_parts)
732
- self.target_profile['N (NH4+)'] = TOTAL_NITROGEN * (NH4_RATIO / total_parts)
733
  self.initial_n_profile = {
734
  "NO3-": self.target_profile['N (NO3-)'],
735
  "NH4+": self.target_profile['N (NH4+)']
@@ -743,56 +747,35 @@ class NutrientCalculator:
743
  }
744
  return labels.get(element, element)
745
 
746
-
747
  def _balance_nitrogen(self):
748
- # Целевые значения NH₄⁺ и NO₃⁻
749
  total_parts = self.NO3_RATIO + self.NH4_RATIO
750
  target_nh4 = (self.TOTAL_NITROGEN * self.NH4_RATIO) / total_parts
751
  target_no3 = self.TOTAL_NITROGEN - target_nh4
752
 
753
- # Вклад NH₄NO₃
754
- nh4no3_nh4 = target_nh4
755
- nh4no3_no3 = nh4no3_nh4 # NH₄NO₃ вносит оба вида азота
756
- self._apply("Аммоний азотнокислый", "N (NH4+)", nh4no3_nh4)
757
-
758
- # Оставшийся NO₃⁻ (цель - вклад NH₄NO₃)
759
- remaining_no3 = target_no3 - nh4no3_no3
760
- if remaining_no3 > 0.1:
761
- # Распределить между Ca(NO₃)₂ и KNO₃ (например, 70/30)
762
- ca_no3_part = remaining_no3 * 0.7
763
- k_no3_part = remaining_no3 * 0.3
764
- self._apply("Кальциевая селитра", "N (NO3-)", ca_no3_part)
765
- self._apply("Калий азотнокислый", "N (NO3-)", k_no3_part)
766
-
767
-
768
- def calculate(self):
769
- try:
770
- # 1. Всё, что не связано с азотом (например, Mg)
771
- self._apply("Сульфат магния", "Mg", self.target_profile['Mg'])
772
 
773
- # 2. Балансировка азота (NH₄⁺/NO₃⁻)
774
- self._balance_nitrogen() # <-- Ваш новый блок
 
775
 
776
- # 3. Кальций и фосфор (после азота!)
777
- self._apply("Кальциевая селитра", "Ca", self.target_profile['Ca'])
778
- self._apply("Монофосфат калия", "P", self.target_profile['P'])
779
-
780
- # 4. Калий и сера (коррекция)
781
- self._apply_k_sulfate()
782
-
783
- # 5. Последние проверки (например, дефицит калия)
784
- k_deficit = self.target_profile['K'] - self.actual_profile['K']
785
- if k_deficit > 0.1:
786
- self._apply("Калий азотнокислый", "K", k_deficit)
787
 
788
- return self.results
789
- except Exception as e:
790
- print(f"Ошибка: {str(e)}")
791
- raise
792
-
793
-
 
794
 
795
  def _apply(self, fert_name, main_element, required_ppm):
 
796
  if required_ppm <= 0:
797
  return
798
 
@@ -827,6 +810,7 @@ class NutrientCalculator:
827
  raise
828
 
829
  def _apply_k_sulfate(self):
 
830
  fert = "Калий сернокислый"
831
  k_def = self.target_profile['K'] - self.actual_profile['K']
832
  s_def = self.target_profile['S'] - self.actual_profile['S']
@@ -835,27 +819,43 @@ class NutrientCalculator:
835
  return
836
 
837
  try:
 
838
  if s_def > 0.1:
839
- s_content = self.fertilizers[fert]["S"]
840
- grams_s = (s_def * self.volume) / (s_content * 1000)
841
-
842
- k_content = self.fertilizers[fert]["K"]
843
- k_from_s = (grams_s * k_content * 1000) / self.volume
844
-
845
- if k_from_s > k_def and k_def > 0.1:
846
- grams = (k_def * self.volume) / (k_content * 1000)
847
- else:
848
- grams = grams_s
849
-
850
  self._apply(fert, "S", s_def)
 
 
 
851
  except Exception as e:
852
  print(f"Ошибка при расчёте сульфата калия: {str(e)}")
853
  raise
854
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
855
  def calculate_ec(self):
 
856
  return round(self.total_ec, 2)
857
 
858
  def print_report(self):
 
859
  try:
860
  print("\n" + "="*60)
861
  print("ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА (ИТОГО):")
@@ -884,7 +884,7 @@ class NutrientCalculator:
884
  round(data['вклад в EC'], 3),
885
  "\n".join(adds)
886
  ])
887
- print(tabulate(fert_table,
888
  headers=["Удобрение", "Граммы", "Миллиграммы", "EC (мСм/см)", "Добавит"]))
889
 
890
  print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
@@ -906,7 +906,7 @@ if __name__ == "__main__":
906
  try:
907
  calculator = NutrientCalculator(volume_liters=VOLUME_LITERS)
908
  calculator.calculate()
909
- calculator.print_report() # Правильный вызов метода класса
910
  except Exception as e:
911
  print(f"Критическая ошибка: {str(e)}")
912
 
@@ -916,10 +916,6 @@ if __name__ == "__main__":
916
 
917
 
918
 
919
-
920
-
921
-
922
-
923
  from flask import request, jsonify
924
 
925
  def round_floats(obj, ndigits=3):
 
685
 
686
 
687
 
 
688
  from tabulate import tabulate
689
 
690
  # Константы
 
695
 
696
  # Коэффициенты электропроводности
697
  EC_COEFFICIENTS = {
698
+ 'P': 0.0012, 'K': 0.0018, 'Mg': 0.0015,
699
+ 'Ca': 0.0016, 'S': 0.0014,
700
  'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
701
  }
702
 
 
722
  self.results = {}
723
  self.target_profile = BASE_PROFILE.copy()
724
  self.actual_profile = {k: 0.0 for k in BASE_PROFILE}
725
+ self.fertilizers = NUTRIENT_CONTENT_IN_FERTILIZERS
726
  self.total_ec = 0.0
727
+
728
+ # Добавляем константы как атрибуты
729
+ self.NO3_RATIO = NO3_RATIO
730
+ self.NH4_RATIO = NH4_RATIO
731
+ self.TOTAL_NITROGEN = TOTAL_NITROGEN
732
 
733
  # Расчёт азота
734
+ total_parts = self.NO3_RATIO + self.NH4_RATIO
735
+ self.target_profile['N (NO3-)'] = self.TOTAL_NITROGEN * (self.NO3_RATIO / total_parts)
736
+ self.target_profile['N (NH4+)'] = self.TOTAL_NITROGEN * (self.NH4_RATIO / total_parts)
737
  self.initial_n_profile = {
738
  "NO3-": self.target_profile['N (NO3-)'],
739
  "NH4+": self.target_profile['N (NH4+)']
 
747
  }
748
  return labels.get(element, element)
749
 
 
750
  def _balance_nitrogen(self):
751
+ """Балансировка азотных компонентов"""
752
  total_parts = self.NO3_RATIO + self.NH4_RATIO
753
  target_nh4 = (self.TOTAL_NITROGEN * self.NH4_RATIO) / total_parts
754
  target_no3 = self.TOTAL_NITROGEN - target_nh4
755
 
756
+ # Вносим NH₄⁺ через NH₄NO₃
757
+ self._apply("Аммоний азотнокислый", "N (NH4+)", target_nh4)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
758
 
759
+ # Оставшийся NO₃⁻ распределяем
760
+ remaining_no3 = target_no3 - self.fertilizers["Аммоний азотнокислый"]["N (NO3-)"] * \
761
+ (target_nh4 / self.fertilizers["Аммоний азотнокислый"]["N (NH4+)"])
762
 
763
+ if remaining_no3 > 0.1:
764
+ # Сначала вносим через Ca(NO₃)₂ (для кальция)
765
+ ca_needed = self.target_profile['Ca'] - self.actual_profile['Ca']
766
+ max_ca_no3 = ca_needed / self.fertilizers["Кальциевая селитра"]["Ca"] * \
767
+ self.fertilizers["Кальциевая селитра"]["N (NO3-)"]
 
 
 
 
 
 
768
 
769
+ ca_no3_part = min(remaining_no3, max_ca_no3)
770
+ self._apply("Кальциевая селитра", "N (NO3-)", ca_no3_part)
771
+
772
+ # Остаток через KNO₃
773
+ remaining_no3 -= ca_no3_part
774
+ if remaining_no3 > 0.1:
775
+ self._apply("Калий азотнокислый", "N (NO3-)", remaining_no3)
776
 
777
  def _apply(self, fert_name, main_element, required_ppm):
778
+ """Применение удобрения с расчётом вносимых элементов"""
779
  if required_ppm <= 0:
780
  return
781
 
 
810
  raise
811
 
812
  def _apply_k_sulfate(self):
813
+ """Коррекция калия и серы через сульфат калия"""
814
  fert = "Калий сернокислый"
815
  k_def = self.target_profile['K'] - self.actual_profile['K']
816
  s_def = self.target_profile['S'] - self.actual_profile['S']
 
819
  return
820
 
821
  try:
822
+ # Всегда применяем по сере, если есть дефицит
823
  if s_def > 0.1:
 
 
 
 
 
 
 
 
 
 
 
824
  self._apply(fert, "S", s_def)
825
+ # Отдельно применяем по калию, если остался дефицит
826
+ if k_def > 0.1:
827
+ self._apply(fert, "K", k_def)
828
  except Exception as e:
829
  print(f"Ошибка при расчёте сульфата калия: {str(e)}")
830
  raise
831
 
832
+ def calculate(self):
833
+ """Основной метод расчёта питательного раствора"""
834
+ try:
835
+ # 1. Всё, что не связано с азотом (например, Mg)
836
+ self._apply("Сульфат магния", "Mg", self.target_profile['Mg'])
837
+
838
+ # 2. Балансировка азота (NH₄⁺/NO₃⁻)
839
+ self._balance_nitrogen()
840
+
841
+ # 3. Кальций и фосфор (после азота!)
842
+ self._apply("Кальциевая селитра", "Ca", self.target_profile['Ca'])
843
+ self._apply("Монофосфат калия", "P", self.target_profile['P'])
844
+
845
+ # 4. Калий и сера (коррекция)
846
+ self._apply_k_sulfate()
847
+
848
+ return self.results
849
+ except Exception as e:
850
+ print(f"Ошибка: {str(e)}")
851
+ raise
852
+
853
  def calculate_ec(self):
854
+ """Расчёт общей электропроводности"""
855
  return round(self.total_ec, 2)
856
 
857
  def print_report(self):
858
+ """Вывод отчёта по расчёту"""
859
  try:
860
  print("\n" + "="*60)
861
  print("ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА (ИТОГО):")
 
884
  round(data['вклад в EC'], 3),
885
  "\n".join(adds)
886
  ])
887
+ print(tabulate(fert_table,
888
  headers=["Удобрение", "Граммы", "Миллиграммы", "EC (мСм/см)", "Добавит"]))
889
 
890
  print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
 
906
  try:
907
  calculator = NutrientCalculator(volume_liters=VOLUME_LITERS)
908
  calculator.calculate()
909
+ calculator.print_report()
910
  except Exception as e:
911
  print(f"Критическая ошибка: {str(e)}")
912
 
 
916
 
917
 
918
 
 
 
 
 
919
  from flask import request, jsonify
920
 
921
  def round_floats(obj, ndigits=3):