DmitrMakeev commited on
Commit
2085c6d
·
verified ·
1 Parent(s): 8edd6e0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +112 -80
app.py CHANGED
@@ -708,112 +708,144 @@ def nutri_call():
708
 
709
 
710
 
711
-
712
 
713
 
714
  from tabulate import tabulate
715
  import numpy as np
716
- import numpy as np
717
 
718
- # Глобальные параметры
719
- TOTAL_NITROGEN = 120.0 # Общее количество азота
720
- NO3_RATIO = 8.25 # Соотношение NO3:NH4
721
- NH4_RATIO = 1.0 # Соотношение NH4:NO3
722
- VOLUME_LITERS = 100 # Объем раствора
723
 
724
- # Целевые значения
725
  BASE_PROFILE = {
726
- 'P': 31.000, 'K': 210.000, 'Mg': 24.000,
727
- 'Ca': 84.000, 'S': 56.439,
728
- 'N (NO3-)': 0, 'N (NH4+)': 0
729
  }
730
 
731
- NUTRIENT_CONTENT_IN_FERTILIZERS = {
 
732
  "Кальциевая селитра": {"N (NO3-)": 0.11863, "Ca": 0.16972},
733
  "Калий азотнокислый": {"N (NO3-)": 0.136, "K": 0.382},
734
  "Калий сернокислый": {"K": 0.44874, "S": 0.18401},
735
  "Аммоний азотнокислый": {"N (NO3-)": 0.17499, "N (NH4+)": 0.17499},
736
  "Сульфат магния": {"Mg": 0.09861, "S": 0.13010},
737
  "Монофосфат калия": {"P": 0.218, "K": 0.275},
738
- "Сульфат кальция": {"Ca": 0.23, "S": 0.186},
739
- "Кольцевая селитра": {"N (NO3-)": 0.15, "Ca": 0.20} # Новое удобрение
740
  }
741
 
742
- EC_COEFFICIENTS = {
743
- 'P': 0.0012, 'K': 0.0018, 'Mg': 0.0015,
744
- 'Ca': 0.0016, 'S': 0.0014,
745
- 'N (NO3-)': 0.0017, 'N (NH4+)': 0.0019
746
- }
747
-
748
- nutrients_stencil = list(BASE_PROFILE.keys())
749
-
750
-
751
- class NutrientCalculator:
752
  def __init__(self):
753
  self.volume = VOLUME_LITERS
754
- self.target_profile = BASE_PROFILE.copy()
755
- self.fertilizers = NUTRIENT_CONTENT_IN_FERTILIZERS
756
- self.nutrients_stencil = nutrients_stencil
757
-
758
- # Расчёт азота
759
- total_parts = NO3_RATIO + NH4_RATIO
760
- self.target_profile['N (NO3-)'] = TOTAL_NITROGEN * (NO3_RATIO / total_parts)
761
- self.target_profile['N (NH4+)'] = TOTAL_NITROGEN * (NH4_RATIO / total_parts)
762
-
763
- # Целевой профиль как вектор
764
- self.target_vector = np.array([self.target_profile[nutrient] for nutrient in self.nutrients_stencil])
 
765
 
766
  def calculate(self):
767
- try:
768
- # Построение матрицы A (содержание элементов в удобрениях)
769
- fertilizer_names = list(self.fertilizers.keys())
770
- A = np.zeros((len(self.nutrients_stencil), len(fertilizer_names)))
771
- for i, nutrient in enumerate(self.nutrients_stencil):
772
- for j, fert_name in enumerate(fertilizer_names):
773
- if nutrient in self.fertilizers[fert_name]:
774
- A[i, j] = self.fertilizers[fert_name][nutrient]
775
-
776
- # Формирование вектора B (целевые значения в ppm)
777
- B = self.target_vector * self.volume / 1000 # Перевод ppm в граммы
778
-
779
- # Решение системы уравнений A @ X = B
780
- X, residuals, rank, s = np.linalg.lstsq(A, B, rcond=None)
781
-
782
- # Формирование результата
783
- results = {}
784
- for i, fert_name in enumerate(fertilizer_names):
785
- if X[i] > 0:
786
- results[fert_name] = X[i]
787
-
788
- return results
789
 
790
- except Exception as e:
791
- print(f"Ошибка при расчёте: {str(e)}")
792
- raise
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
793
 
794
  def generate_report(self, results):
795
- """Генерация отчета с фактическими данными"""
796
- try:
797
- fertilizer_report = "Фактически добавленные удобрения (в граммах):\n"
798
- for fert_name, grams in results.items():
799
- fertilizer_report += f" - {fert_name}: {grams:.2f} г\n"
800
-
801
- return fertilizer_report
802
- except Exception as e:
803
- print(f"Ошибка при выводе отчёта: {str(e)}")
804
- raise
805
-
 
 
 
 
 
 
806
 
 
807
  if __name__ == "__main__":
808
- try:
809
- calculator = NutrientCalculator()
810
- results = calculator.calculate()
811
- if results:
812
- print(calculator.generate_report(results))
813
- else:
814
- print("Решение не найдено.")
815
- except Exception as e:
816
- print(f"Критическая ошибка: {str(e)}")
817
 
818
 
819
  @app.route('/calculation', methods=['POST'])
 
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.25
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:
786
+ self.results[name] = {'граммы': 0.0}
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
  @app.route('/calculation', methods=['POST'])