DmitrMakeev commited on
Commit
24c29c0
·
verified ·
1 Parent(s): ef52acf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -80
app.py CHANGED
@@ -707,79 +707,73 @@ def nutri_call():
707
 
708
 
709
 
710
-
711
 
712
 
713
  from tabulate import tabulate
714
- import numpy as np
715
 
716
- # Константы
717
- TOTAL_NITROGEN = 120.0
718
- NO3_RATIO = 8.35
719
- NH4_RATIO = 1.0
720
- VOLUME_LITERS = 100
721
-
722
- # Целевой профиль (ppm)
723
- BASE_PROFILE = {
724
- 'P': 31.0, 'K': 210.0, 'Mg': 24.0,
725
- 'Ca': 84.0, 'S': 56.439,
726
- 'N (NO3-)': 0, 'N (NH4+)': 0 # Будет рассчитано
727
- }
728
-
729
- # Состав удобрений (доли)
730
- NUTRIENT_CONTENT = {
731
- "Кальциевая селитра": {"N (NO3-)": 0.11863, "Ca": 0.16972},
732
- "Калий азотнокислый": {"N (NO3-)": 0.136, "K": 0.382},
733
- "Калий сернокислый": {"K": 0.44874, "S": 0.18401},
734
- "Аммоний азотнокислый": {"N (NO3-)": 0.17499, "N (NH4+)": 0.17499},
735
- "Сульфат магния": {"Mg": 0.09861, "S": 0.13010},
736
- "Монофосфат калия": {"P": 0.218, "K": 0.275},
737
- "Сульфат кальция": {"Ca": 0.23, "S": 0.186}
738
  }
739
 
740
- class PrecisionNutrientCalculator:
741
- def __init__(self):
742
- self.volume = VOLUME_LITERS
743
- self.target = self._calculate_nitrogen_profile()
744
- self.fertilizers = NUTRIENT_CONTENT
745
- self.results = {}
746
- self.actual = {k: 0.0 for k in self.target}
 
 
 
 
 
 
 
 
 
 
747
 
748
- def _calculate_nitrogen_profile(self):
749
- """Расчет азотных компонентов"""
750
- profile = BASE_PROFILE.copy()
751
- total = NO3_RATIO + NH4_RATIO
752
- profile['N (NO3-)'] = TOTAL_NITROGEN * (NO3_RATIO / total)
753
- profile['N (NH4+)'] = TOTAL_NITROGEN * (NH4_RATIO / total)
754
- return profile
755
 
756
  def calculate(self):
757
- """Основной метод расчета с проверкой"""
758
  # 1. Вносим кальциевую селитру (Ca + NO3)
759
- self._apply_fertilizer("Кальциевая селитра", "Ca", self.target['Ca'])
760
 
761
  # 2. Вносим аммонийный азот
762
- self._apply_fertilizer("Аммоний азотнокислый", "N (NH4+)", self.target['N (NH4+)'])
763
 
764
  # 3. Компенсируем NO3 калийной селитрой
765
- no3_needed = self.target['N (NO3-)'] - self.actual['N (NO3-)']
766
  if no3_needed > 0:
767
  self._apply_fertilizer("Калий азотнокислый", "N (NO3-)", no3_needed)
768
 
769
  # 4. Вносим фосфор
770
- self._apply_fertilizer("Монофосфат калия", "P", self.target['P'])
771
 
772
  # 5. Вносим магний
773
- self._apply_fertilizer("Сульфат магния", "Mg", self.target['Mg'])
774
 
775
  # 6. Балансируем калий и серу
776
  self._balance_k_s()
777
 
778
  return self._verify_results()
779
 
780
- def _apply_fertilizer(self, name, main_element, target_ppm):
781
- """Точное внесение удобрения для конкретного элемента"""
782
- content = self.fertilizers[name][main_element]
783
  grams = (target_ppm * self.volume) / (content * 1000)
784
 
785
  if name not in self.results:
@@ -787,68 +781,78 @@ class PrecisionNutrientCalculator:
787
 
788
  self.results[name]['граммы'] += grams
789
 
790
- # Учитываем все элементы из удобрения
791
- for element, percent in self.fertilizers[name].items():
792
- added_ppm = (grams * percent * 1000) / self.volume
793
- self.actual[element] += added_ppm
794
 
795
  def _balance_k_s(self):
796
- """Балансировка калия и серы"""
797
- k_needed = self.target['K'] - self.actual['K']
798
- s_needed = self.target['S'] - self.actual['S']
799
 
800
- # Используем K2SO4 если нужна и сера и калий
801
  if k_needed > 0 and s_needed > 0:
802
  k_from_k2so4 = min(k_needed, s_needed * 0.44874/0.18401)
803
  self._apply_fertilizer("Калий сернокислый", "K", k_from_k2so4)
804
 
805
  # Добираем остаток калия KNO3
806
- remaining_k = self.target['K'] - self.actual['K']
807
  if remaining_k > 0:
808
  self._apply_fertilizer("Калий азотнокислый", "K", remaining_k)
809
 
810
  def _verify_results(self):
811
- """Проверка соответствия целевому профилю"""
812
  deficits = {}
813
- for element in self.target:
814
- diff = self.target[element] - self.actual[element]
815
  if abs(diff) > 0.1: # Допустимая погрешность 0.1 ppm
816
- deficits[element] = round(diff, 3)
817
 
818
  return {
819
  'fertilizers': {k: round(v['граммы'], 3) for k, v in self.results.items()},
820
  'actual_profile': {k: round(v, 3) for k, v in self.actual.items()},
821
  'deficits': deficits,
822
- 'success': len(deficits) == 0
823
  }
824
 
825
  def generate_report(self, results):
826
- """Генерация читаемого отчета"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
827
  report = "РЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:\n"
828
- for fert, data in results['fertilizers'].items():
829
- report += f"{fert}: {data} г\n"
830
 
831
- report += "\nФАКТИЧЕСКИЙ ПРОФИЛЬ (ppm):\n"
832
- for element, value in results['actual_profile'].items():
833
- report += f"{element}: {value} (цель: {self.target[element]})\n"
 
 
 
834
 
835
  if results['deficits']:
836
- report += "\nДЕФИЦИТЫ:\n"
837
- for element, diff in results['deficits'].items():
838
- report += f"{element}: не хватает {diff} ppm\n"
839
- else:
840
- report += "\nВсе элементы сбалансированы идеально!"
841
 
842
  return report
843
 
844
- # Пример использования
845
- if __name__ == "__main__":
846
- calculator = PrecisionNutrientCalculator()
847
- results = calculator.calculate()
848
- print(calculator.generate_report(results))
849
-
850
-
851
-
852
 
853
  @app.route('/calculation', methods=['POST'])
854
  def handle_calculation():
 
707
 
708
 
709
 
 
710
 
711
 
712
  from tabulate import tabulate
 
713
 
714
+ # Входные данные
715
+ INPUT_DATA = {
716
+ "fertilizerConstants": {
717
+ "Кальциевая селитра": {"N (NO3-)": 0.11863, "Ca": 0.16972},
718
+ "Калий азотнокислый": {"N (NO3-)": 0.13854, "K": 0.36672},
719
+ "Аммоний азотнокислый": {"N (NO3-)": 0.17499, "N (NH4+)": 0.17499},
720
+ "Сульфат магния": {"Mg": 0.10220, "S": 0.13483},
721
+ "Монофосфат калия": {"P": 0.22761, "K": 0.28731},
722
+ "Калий сернокислый": {"K": 0.44874, "S": 0.18401}
723
+ },
724
+ "profileSettings": {
725
+ "P": 60, "K": 194, "Mg": 48.5, "Ca": 121.25, "S": 79.445,
726
+ "NO3_RAT": 9.5, "TOTAL_NITROG": 138.57, "liters": 100
727
+ }
 
 
 
 
 
 
 
 
728
  }
729
 
730
+ class NutrientCalculator:
731
+ def __init__(self, input_data):
732
+ self.fertilizers = input_data["fertilizerConstants"]
733
+ self.profile = input_data["profileSettings"]
734
+ self.volume = self.profile["liters"]
735
+
736
+ # Рассчитываем азотные компоненты
737
+ total_parts = self.profile["NO3_RAT"] + 1
738
+ self.target = {
739
+ 'P': self.profile["P"],
740
+ 'K': self.profile["K"],
741
+ 'Mg': self.profile["Mg"],
742
+ 'Ca': self.profile["Ca"],
743
+ 'S': self.profile["S"],
744
+ 'N (NO3-)': self.profile["TOTAL_NITROG"] * (self.profile["NO3_RAT"] / total_parts),
745
+ 'N (NH4+)': self.profile["TOTAL_NITROG"] * (1 / total_parts)
746
+ }
747
 
748
+ self.actual = {k: 0.0 for k in self.target}
749
+ self.results = {}
 
 
 
 
 
750
 
751
  def calculate(self):
 
752
  # 1. Вносим кальциевую селитру (Ca + NO3)
753
+ self._apply_fertilizer("Кальциевая селитра", "Ca", self.target["Ca"])
754
 
755
  # 2. Вносим аммонийный азот
756
+ self._apply_fertilizer("Аммоний азотнокислый", "N (NH4+)", self.target["N (NH4+)"])
757
 
758
  # 3. Компенсируем NO3 калийной селитрой
759
+ no3_needed = self.target["N (NO3-)"] - self.actual["N (NO3-)"]
760
  if no3_needed > 0:
761
  self._apply_fertilizer("Калий азотнокислый", "N (NO3-)", no3_needed)
762
 
763
  # 4. Вносим фосфор
764
+ self._apply_fertilizer("Монофосфат калия", "P", self.target["P"])
765
 
766
  # 5. Вносим магний
767
+ self._apply_fertilizer("Сульфат магния", "Mg", self.target["Mg"])
768
 
769
  # 6. Балансируем калий и серу
770
  self._balance_k_s()
771
 
772
  return self._verify_results()
773
 
774
+ def _apply_fertilizer(self, name, element, target_ppm):
775
+ """Применение удобрения с точным расчетом"""
776
+ content = self.fertilizers[name][element]
777
  grams = (target_ppm * self.volume) / (content * 1000)
778
 
779
  if name not in self.results:
 
781
 
782
  self.results[name]['граммы'] += grams
783
 
784
+ for el, val in self.fertilizers[name].items():
785
+ added_ppm = (grams * val * 1000) / self.volume
786
+ self.actual[el] += added_ppm
 
787
 
788
  def _balance_k_s(self):
789
+ """Интеллектуальная балансировка K и S"""
790
+ k_needed = self.target["K"] - self.actual["K"]
791
+ s_needed = self.target["S"] - self.actual["S"]
792
 
793
+ # Используем K2SO4 если нужны оба элемента
794
  if k_needed > 0 and s_needed > 0:
795
  k_from_k2so4 = min(k_needed, s_needed * 0.44874/0.18401)
796
  self._apply_fertilizer("Калий сернокислый", "K", k_from_k2so4)
797
 
798
  # Добираем остаток калия KNO3
799
+ remaining_k = self.target["K"] - self.actual["K"]
800
  if remaining_k > 0:
801
  self._apply_fertilizer("Калий азотнокислый", "K", remaining_k)
802
 
803
  def _verify_results(self):
804
+ """Проверка точности соответствия"""
805
  deficits = {}
806
+ for el in self.target:
807
+ diff = self.target[el] - self.actual[el]
808
  if abs(diff) > 0.1: # Допустимая погрешность 0.1 ppm
809
+ deficits[el] = round(diff, 3)
810
 
811
  return {
812
  'fertilizers': {k: round(v['граммы'], 3) for k, v in self.results.items()},
813
  'actual_profile': {k: round(v, 3) for k, v in self.actual.items()},
814
  'deficits': deficits,
815
+ 'total_ppm': round(sum(self.actual.values()), 3)
816
  }
817
 
818
  def generate_report(self, results):
819
+ """Генерация красивого отчета"""
820
+ # Таблица удобрений
821
+ fert_table = []
822
+ for name, data in results['fertilizers'].items():
823
+ fert_table.append([name, f"{data} г"])
824
+
825
+ # Таблица элементов
826
+ element_table = []
827
+ for el in sorted(self.target.keys()):
828
+ element_table.append([
829
+ el,
830
+ f"{self.target[el]} ppm",
831
+ f"{results['actual_profile'][el]} ppm",
832
+ f"{results['actual_profile'][el] - self.target[el]:+.2f} ppm"
833
+ ])
834
+
835
  report = "РЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:\n"
836
+ report += tabulate(fert_table, headers=["Удобрение", "Количество"], tablefmt="grid")
 
837
 
838
+ report += "\n\nБАЛАНС ЭЛЕМЕНТОВ:\n"
839
+ report += tabulate(element_table,
840
+ headers=["Элемент", "Цель", "Факт", "Отклонение"],
841
+ tablefmt="grid")
842
+
843
+ report += f"\n\nОбщая концентрация: {results['total_ppm']} ppm"
844
 
845
  if results['deficits']:
846
+ report += "\n\nВНИМАНИЕ: Обнаружены небольшие отклонения:"
847
+ for el, diff in results['deficits'].items():
848
+ report += f"\n- {el}: не хватает {abs(diff)} ppm"
 
 
849
 
850
  return report
851
 
852
+ # Запуск расчета
853
+ calculator = NutrientCalculator(INPUT_DATA)
854
+ results = calculator.calculate()
855
+ print(calculator.generate_report(results))
 
 
 
 
856
 
857
  @app.route('/calculation', methods=['POST'])
858
  def handle_calculation():