DmitrMakeev commited on
Commit
506e0b6
·
verified ·
1 Parent(s): 71ded0a

Update app.py

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