DmitrMakeev commited on
Commit
7dbf3d5
·
verified ·
1 Parent(s): 4d59d9b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -87
app.py CHANGED
@@ -694,38 +694,16 @@ def nutri_call():
694
 
695
 
696
 
697
-
698
- from tabulate import tabulate
699
-
700
- # Входные данные (пример)
701
- INPUT_DATA = {
702
- "fertilizerConstants": {
703
- "Кальциевая селитра": {"N (NO3-)": 0.11863, "Ca": 0.16972},
704
- "Калий азотнокислый": {"N (NO3-)": 0.13854, "K": 0.36672},
705
- "Аммоний азотнокислый": {"N (NO3-)": 0.17499, "N (NH4+)": 0.17499},
706
- "Сульфат магния": {"Mg": 0.10220, "S": 0.13483},
707
- "Монофосфат калия": {"P": 0.22761, "K": 0.28731},
708
- "Калий сернокислый": {"K": 0.44874, "S": 0.18401},
709
- "Кальций хлорид": {"Ca": 0.272, "Cl": 0.483}
710
- },
711
- "profileSettings": {
712
- "P": 60, "K": 194, "Mg": 48.5, "Ca": 89.25, "S": 79.445, "CaCl": 38.5,
713
- "NO3_RAT": 1.5, "TOTAL_NITROG": 138.57, "liters": 100,
714
- "activation_cacl": 5, # Добавлено
715
- "enhancement_cacl": 3 # Добавлено
716
- }
717
- }
718
-
719
  class NutrientCalculator:
720
  def __init__(self, fertilizer_constants, profile_settings, liters, rounding_precision, activation_cacl, enhancement_cacl):
721
  self.fertilizers = fertilizer_constants
722
  self.profile = profile_settings
723
  self.volume = liters
724
- self.rounding_precision = rounding_precision # Точность округления
725
 
726
  # Новые параметры
727
- self.activation_cacl = activation_cacl # Активация CaCl
728
- self.enhancement_cacl = enhancement_cacl # Усиление CaCl
729
 
730
  total_parts = self.profile["NO3_RAT"] + 1
731
  self.target = {
@@ -742,114 +720,80 @@ class NutrientCalculator:
742
  self.results = {fert: {'граммы': 0.0} for fert in self.fertilizers}
743
 
744
  def calculate(self):
745
- # 1. Вносим аммонийный азот
746
  self._apply_fertilizer("Аммоний азотнокислый", "N (NH4+)", self.target["N (NH4+)"])
747
-
748
- # 2. Вносим фосфор
749
  self._apply_fertilizer("Монофосфат калия", "P", self.target["P"])
750
-
751
- # 3. Вносим магний
752
  self._apply_fertilizer("Сульфат магния", "Mg", self.target["Mg"])
753
-
754
- # 4. Балансируем калий и серу
755
  self._balance_k_s()
756
-
757
- # 5. Распределяем кальций между селитрой и хлоридом
758
  self._distribute_calcium()
759
-
760
- # 6. Компенсируем NO3 калийной селитрой
761
  no3_needed = self.target["N (NO3-)"] - self.actual["N (NO3-)"]
762
  if no3_needed > 0:
763
  self._apply_fertilizer("Калий азотнокислый", "N (NO3-)", no3_needed)
764
-
765
  return self._verify_results()
766
 
767
  def _apply_fertilizer(self, name, element, target_ppm):
768
  if name not in self.fertilizers:
769
- raise KeyError(f"Удобрение '{name}' не найдено в fertilizerConstants!")
770
-
771
- content = self.fertilizers[name].get(element, 0) # Получаем содержание элемента
772
  if content == 0:
773
  print(f"ПРЕДУПРЕЖДЕНИЕ: Удобрение '{name}' не содержит элемент '{element}'")
774
  return
775
-
776
  grams = (target_ppm * self.volume) / (content * 1000)
777
- self.results[name]['граммы'] += round(grams, self.rounding_precision) # Округляем до заданной точности
778
-
779
  for el, val in self.fertilizers[name].items():
780
  added_ppm = (grams * val * 1000) / self.volume
781
  if el in self.actual:
782
  self.actual[el] += round(added_ppm, self.rounding_precision)
783
 
784
  def _balance_k_s(self):
785
- """Балансировка калия и серы"""
786
  k_needed = self.target["K"] - self.actual["K"]
787
  s_needed = self.target["S"] - self.actual["S"]
788
-
789
  if k_needed > 0 and s_needed > 0:
790
- # Берем динамические значения из fertilizerConstants
791
  k_fraction = self.fertilizers["Калий сернокислый"].get("K", 0)
792
  s_fraction = self.fertilizers["Калий сернокислый"].get("S", 0)
793
-
794
  if k_fraction == 0 or s_fraction == 0:
795
- print("ПРЕДУПРЕЖДЕНИЕ: Удобрение 'Калий сернокислый' содержит нулевые значения для K или S!")
796
  return
797
-
798
  k_from_k2so4 = min(k_needed, s_needed * k_fraction / s_fraction)
799
  self._apply_fertilizer("Калий сернокислый", "K", k_from_k2so4)
800
-
801
  remaining_k = self.target["K"] - self.actual["K"]
802
  if remaining_k > 0:
803
  self._apply_fertilizer("Калий азотнокислый", "K", remaining_k)
804
 
805
  def _distribute_calcium(self):
806
- ca_target = self.target["Ca"] # Общий кальций
807
  no3_ratio = self.profile["NO3_RAT"]
808
-
809
- # Проверка соотношения NO3/NH4
810
- if no3_ratio >= self.activation_cacl: # Заменили "5" на self.activation_cacl
811
  print(f"Соотношение NO3/NH4 >= {self.activation_cacl}. Кальций хлористый не добавляется.")
812
  remaining_ca = ca_target
813
  else:
814
- # Определяем, сколько кальция взять из хлористого кальция
815
- cacl_ratio = self.enhancement_cacl # Заменили "0.1" на self.enhancement_cacl
816
  cacl_target = ca_target * cacl_ratio
817
-
818
- # Вносим кальций из хлористого кальция
819
  if cacl_target > 0:
820
  self._apply_fertilizer("Кальций хлорид", "Ca", cacl_target)
821
-
822
- # Оставшийся кальций берем из кальциевой селитры
823
  remaining_ca = ca_target - cacl_target
824
-
825
- # Добавляем оставшийся кальций из кальциевой селитры
826
  if remaining_ca > 0:
827
  self._apply_fertilizer("Кальциевая селитра", "Ca", remaining_ca)
828
 
829
- def _verify_results(self):
830
- """Проверка результатов расчета"""
831
- deficits = {}
832
- for el in self.target:
833
- diff = self.target[el] - self.actual[el]
834
- if abs(diff) > 0.1:
835
- deficits[el] = round(diff, self.rounding_precision)
836
-
837
- return {
838
- 'fertilizers': {k: round(v['граммы'], self.rounding_precision) for k, v in self.results.items()},
839
- 'actual_profile': {k: round(v, self.rounding_precision) for k, v in self.actual.items()},
840
- 'deficits': deficits,
841
- 'total_ppm': round(sum(self.actual.values()), self.rounding_precision)
842
- }
843
 
844
  def generate_report(self, results):
845
- """Генерация текстового отчета"""
846
  fert_table = []
847
  for name, data in results['fertilizers'].items():
848
  fert_table.append([name, f"{data} г"])
849
-
850
  element_table = []
851
  for el in sorted(self.target.keys()):
852
- if el == "CaCl": # Пропускаем CaCl в отчете
853
  continue
854
  element_table.append([
855
  el,
@@ -857,31 +801,26 @@ class NutrientCalculator:
857
  f"{results['actual_profile'][el]} ppm",
858
  f"{results['actual_profile'][el] - self.target[el]:+.2f} ppm"
859
  ])
860
-
861
  report = "РЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:\n"
862
  report += tabulate(fert_table, headers=["Удобрение", "Количество"], tablefmt="grid")
863
-
864
  report += "\n\nБАЛАНС ЭЛЕМЕНТОВ:\n"
865
  report += tabulate(element_table,
866
  headers=["Элемент", "Цель", "Факт", "Отклонение"],
867
  tablefmt="grid")
868
-
869
  report += f"\n\nОбщая концентрация: {results['total_ppm']} ppm"
870
-
871
  if results['deficits']:
872
  report += "\n\nВНИМАНИЕ: Обнаружены небольшие отклонения:"
873
  for el, diff in results['deficits'].items():
874
  report += f"\n- {el}: не хватает {abs(diff)} ppm"
875
-
876
  return report
877
 
878
  # Извлекаем данные из INPUT_DATA
879
  fertilizer_constants = INPUT_DATA["fertilizerConstants"]
880
  profile_settings = INPUT_DATA["profileSettings"]
881
  liters = profile_settings["liters"]
882
- rounding_precision = 3 # Значение по умолчанию
883
- activation_cacl = profile_settings.get("activation_cacl", 0) # По умолчанию 0
884
- enhancement_cacl = profile_settings.get("enhancement_cacl", 0) # По умолчанию 0
885
 
886
  # Создаем калькулятор
887
  calculator = NutrientCalculator(
@@ -893,6 +832,10 @@ calculator = NutrientCalculator(
893
  enhancement_cacl=enhancement_cacl
894
  )
895
 
 
 
 
 
896
  @app.route('/calculation', methods=['POST'])
897
  def handle_calculation():
898
  try:
 
694
 
695
 
696
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
697
  class NutrientCalculator:
698
  def __init__(self, fertilizer_constants, profile_settings, liters, rounding_precision, activation_cacl, enhancement_cacl):
699
  self.fertilizers = fertilizer_constants
700
  self.profile = profile_settings
701
  self.volume = liters
702
+ self.rounding_precision = rounding_precision
703
 
704
  # Новые параметры
705
+ self.activation_cacl = float(activation_cacl) # Активация CaCl
706
+ self.enhancement_cacl = float(enhancement_cacl) # Усиление CaCl
707
 
708
  total_parts = self.profile["NO3_RAT"] + 1
709
  self.target = {
 
720
  self.results = {fert: {'граммы': 0.0} for fert in self.fertilizers}
721
 
722
  def calculate(self):
 
723
  self._apply_fertilizer("Аммоний азотнокислый", "N (NH4+)", self.target["N (NH4+)"])
 
 
724
  self._apply_fertilizer("Монофосфат калия", "P", self.target["P"])
 
 
725
  self._apply_fertilizer("Сульфат магния", "Mg", self.target["Mg"])
 
 
726
  self._balance_k_s()
 
 
727
  self._distribute_calcium()
 
 
728
  no3_needed = self.target["N (NO3-)"] - self.actual["N (NO3-)"]
729
  if no3_needed > 0:
730
  self._apply_fertilizer("Калий азотнокислый", "N (NO3-)", no3_needed)
 
731
  return self._verify_results()
732
 
733
  def _apply_fertilizer(self, name, element, target_ppm):
734
  if name not in self.fertilizers:
735
+ raise KeyError(f"Удобрение '{name}' не найдено!")
736
+ content = self.fertilizers[name].get(element, 0)
 
737
  if content == 0:
738
  print(f"ПРЕДУПРЕЖДЕНИЕ: Удобрение '{name}' не содержит элемент '{element}'")
739
  return
 
740
  grams = (target_ppm * self.volume) / (content * 1000)
741
+ self.results[name]['граммы'] += round(grams, self.rounding_precision)
 
742
  for el, val in self.fertilizers[name].items():
743
  added_ppm = (grams * val * 1000) / self.volume
744
  if el in self.actual:
745
  self.actual[el] += round(added_ppm, self.rounding_precision)
746
 
747
  def _balance_k_s(self):
 
748
  k_needed = self.target["K"] - self.actual["K"]
749
  s_needed = self.target["S"] - self.actual["S"]
 
750
  if k_needed > 0 and s_needed > 0:
 
751
  k_fraction = self.fertilizers["Калий сернокислый"].get("K", 0)
752
  s_fraction = self.fertilizers["Калий сернокислый"].get("S", 0)
 
753
  if k_fraction == 0 or s_fraction == 0:
754
+ print("ПРЕДУПРЕЖДЕНИЕ: Удобрение 'Калий сернокислый' содержит нулевые значения!")
755
  return
 
756
  k_from_k2so4 = min(k_needed, s_needed * k_fraction / s_fraction)
757
  self._apply_fertilizer("Калий сернокислый", "K", k_from_k2so4)
 
758
  remaining_k = self.target["K"] - self.actual["K"]
759
  if remaining_k > 0:
760
  self._apply_fertilizer("Калий азотнокислый", "K", remaining_k)
761
 
762
  def _distribute_calcium(self):
763
+ ca_target = self.target["Ca"]
764
  no3_ratio = self.profile["NO3_RAT"]
765
+ if no3_ratio >= self.activation_cacl:
 
 
766
  print(f"Соотношение NO3/NH4 >= {self.activation_cacl}. Кальций хлористый не добавляется.")
767
  remaining_ca = ca_target
768
  else:
769
+ cacl_ratio = self.enhancement_cacl
 
770
  cacl_target = ca_target * cacl_ratio
 
 
771
  if cacl_target > 0:
772
  self._apply_fertilizer("Кальций хлорид", "Ca", cacl_target)
 
 
773
  remaining_ca = ca_target - cacl_target
 
 
774
  if remaining_ca > 0:
775
  self._apply_fertilizer("Кальциевая селитра", "Ca", remaining_ca)
776
 
777
+ def _verify_results(self):
778
+ deficits = {}
779
+ for el in self.target:
780
+ diff = self.target[el] - self.actual[el]
781
+ if abs(diff) > 0.1:
782
+ deficits[el] = round(diff, self.rounding_precision)
783
+ return {
784
+ 'fertilizers': {k: round(v['граммы'], self.rounding_precision) for k, v in self.results.items()},
785
+ 'actual_profile': {k: round(v, self.rounding_precision) for k, v in self.actual.items()},
786
+ 'deficits': deficits,
787
+ 'total_ppm': round(sum(self.actual.values()), self.rounding_precision)
788
+ }
 
 
789
 
790
  def generate_report(self, results):
 
791
  fert_table = []
792
  for name, data in results['fertilizers'].items():
793
  fert_table.append([name, f"{data} г"])
 
794
  element_table = []
795
  for el in sorted(self.target.keys()):
796
+ if el == "CaCl":
797
  continue
798
  element_table.append([
799
  el,
 
801
  f"{results['actual_profile'][el]} ppm",
802
  f"{results['actual_profile'][el] - self.target[el]:+.2f} ppm"
803
  ])
 
804
  report = "РЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:\n"
805
  report += tabulate(fert_table, headers=["Удобрение", "Количество"], tablefmt="grid")
 
806
  report += "\n\nБАЛАНС ЭЛЕМЕНТОВ:\n"
807
  report += tabulate(element_table,
808
  headers=["Элемент", "Цель", "Факт", "Отклонение"],
809
  tablefmt="grid")
 
810
  report += f"\n\nОбщая концентрация: {results['total_ppm']} ppm"
 
811
  if results['deficits']:
812
  report += "\n\nВНИМАНИЕ: Обнаружены небольшие отклонения:"
813
  for el, diff in results['deficits'].items():
814
  report += f"\n- {el}: не хватает {abs(diff)} ppm"
 
815
  return report
816
 
817
  # Извлекаем данные из INPUT_DATA
818
  fertilizer_constants = INPUT_DATA["fertilizerConstants"]
819
  profile_settings = INPUT_DATA["profileSettings"]
820
  liters = profile_settings["liters"]
821
+ rounding_precision = 3
822
+ activation_cacl = float(profile_settings.get("activation_cacl", 5))
823
+ enhancement_cacl = float(profile_settings.get("enhancement_cacl", 0.1))
824
 
825
  # Создаем калькулятор
826
  calculator = NutrientCalculator(
 
832
  enhancement_cacl=enhancement_cacl
833
  )
834
 
835
+ # Запуск расчета
836
+ results = calculator.calculate()
837
+ print(calculator.generate_report(results))
838
+
839
  @app.route('/calculation', methods=['POST'])
840
  def handle_calculation():
841
  try: