DmitrMakeev commited on
Commit
ef8678c
·
verified ·
1 Parent(s): 22a31dc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -128
app.py CHANGED
@@ -678,16 +678,15 @@ def view_image():
678
 
679
 
680
 
681
-
682
  from tabulate import tabulate
683
 
684
- # Константы для расчёта
685
- TOTAL_NITROGEN = 125 # ppm
686
- NO3_RATIO = 8.00 # Доля нитратного азота
687
- NH4_RATIO = 1.00 # Доля аммонийного азота
688
- VOLUME_LITERS = 100 # Объём раствора (можно менять)
689
 
690
- # Базовый профиль (7 элементов)
691
  BASE_PROFILE = {
692
  'P': 31.000,
693
  'K': 210.000,
@@ -698,7 +697,6 @@ BASE_PROFILE = {
698
  'N (NH4+)': 0
699
  }
700
 
701
- # База удобрений (6 удобрений)
702
  FERTILIZERS = {
703
  "Кальциевая селитра": {"N (NO3-)": 0.118, "Ca": 0.169},
704
  "Калий азотнокислый": {"N (NO3-)": 0.138, "K": 0.387},
@@ -712,169 +710,126 @@ class NutrientCalculator:
712
  def __init__(self, volume_liters=1.0):
713
  self.volume = volume_liters
714
  self.results = {}
715
- self.profile = BASE_PROFILE.copy()
716
- self.total_ppm = sum(BASE_PROFILE.values()) + TOTAL_NITROGEN
717
  self.fertilizers = FERTILIZERS
718
- self.final_profile = BASE_PROFILE.copy()
719
-
720
- # Рассчитываем целевые значения азота
721
  total_parts = NO3_RATIO + NH4_RATIO
722
- self.target_no3 = TOTAL_NITROGEN * (NO3_RATIO / total_parts)
723
- self.target_nh4 = TOTAL_NITROGEN * (NH4_RATIO / total_parts)
724
  self.initial_n_profile = {
725
- "NO3-": self.target_no3,
726
- "NH4+": self.target_nh4
727
  }
728
 
729
  def calculate(self):
730
- # 1. Вносим сульфат магния (Mg)
731
- self._apply_fertilizer("Сульфат магния", 24.0, "Mg", {"S": "внесет S"})
732
-
733
- # 2. Вносим кальциевую селитру (Ca и NO3)
734
- self._apply_fertilizer("Кальциевая селитра", 84.0, "Ca", {"N (NO3-)": "внесет NO3"})
735
-
736
- # 3. Вносим калий фосфорнокислый (P)
737
- self._apply_fertilizer("Калий фосфорнокислый", 31.0, "P", {"K": "внесет K"})
738
-
739
- # 4. Вносим аммоний азотнокислый (NH4)
740
- self._apply_fertilizer("Аммоний азотнокислый", self.target_nh4, "N (NH4+)", {"N (NO3-)": "внесет NO3"})
741
-
742
- # 5. Вносим калий сернокислый (K и S)
743
- self._apply_potassium_sulfate()
744
-
745
- # 6. Вносим калий азотнокислый (K и NO3)
746
- self._apply_potassium_nitrate()
747
-
748
- # Пересчитываем фактическое содержание азота
749
- self._recalculate_nitrogen()
750
-
751
- # Обновляем финальный профиль
752
- self._update_final_profile()
753
-
754
  return self.results
755
 
756
- def _apply_fertilizer(self, name, ppm_needed, main_element, additions):
757
- content = self.fertilizers[name][main_element]
758
- grams = (ppm_needed * self.volume) / (content * 1000)
759
-
760
- added = {}
761
- for element, label in additions.items():
762
- added_amount = grams * self.fertilizers[name][element] * 1000 / self.volume
763
- added[label] = round(added_amount, 1)
764
- # Уменьшаем дефицит по этому элементу
765
- if element in self.final_profile:
766
- self.final_profile[element] -= added_amount
767
-
768
- self.results[name] = {
769
  'граммы': round(grams, 3),
770
- 'миллиграммы': int(grams * 1000),
771
- **added
772
  }
773
-
774
- # Уменьшаем дефицит по основному элементу
775
- self.final_profile[main_element] -= ppm_needed
776
 
777
- def _apply_potassium_sulfate(self):
778
- # Рассчитываем необходимое количество для покрытия дефицита
779
- k_content = self.fertilizers["Калий сернокислый"]["K"]
780
- s_content = self.fertilizers["Калий сернокислый"]["S"]
781
-
782
- # Рассчитываем граммы для покрытия дефицита
783
- grams_k = (self.profile['K'] * self.volume) / (k_content * 1000)
784
- grams_s = (self.profile['S'] * self.volume) / (s_content * 1000)
785
- grams = max(grams_k, grams_s) # Берем максимальное значение
786
-
787
- added_k = grams * k_content * 1000 / self.volume
788
- added_s = grams * s_content * 1000 / self.volume
789
 
790
- self.results["Калий сернокислый"] = {
 
 
 
 
 
 
 
 
 
 
 
 
 
791
  'граммы': round(grams, 3),
792
- 'миллиграммы': int(grams * 1000),
793
- 'внесет K': round(added_k, 1),
794
- 'внесет S': round(added_s, 1)
795
  }
796
-
797
- # Обновляем финальный профиль
798
- self.final_profile['K'] -= added_k
799
- self.final_profile['S'] -= added_s
800
-
801
- def _apply_potassium_nitrate(self):
802
- # Рассчитываем остаточную потребность в калии
803
- k_content = self.fertilizers["Калий азотнокислый"]["K"]
804
- n_content = self.fertilizers["Калий азотнокислый"]["N (NO3-)"]
805
-
806
- grams = (self.profile['K'] * self.volume) / (k_content * 1000)
807
- added_k = grams * k_content * 1000 / self.volume
808
- added_n = grams * n_content * 1000 / self.volume
809
 
810
- self.results["Калий азотнокислый"] = {
 
 
 
 
 
 
 
 
 
 
 
 
 
811
  'граммы': round(grams, 3),
812
- 'миллиграммы': int(grams * 1000),
813
- 'внесет K': round(added_k, 1),
814
- 'внесет NO3': round(added_n, 1)
815
  }
816
-
817
- # Обновляем финальный профиль
818
- self.final_profile['K'] -= added_k
819
- self.final_profile['N (NO3-)'] += added_n
820
-
821
- def _recalculate_nitrogen(self):
822
- # Суммируем весь внесенный азот
823
- total_no3 = sum(f.get('внесет NO3', 0) for f in self.results.values())
824
- total_nh4 = sum(f.get('внесет NH4', 0) for f in self.results.values())
825
-
826
- # Обновляем профиль
827
- self.profile['N (NO3-)'] = total_no3
828
- self.profile['N (NH4+)'] = total_nh4
829
 
830
- def _update_final_profile(self):
831
- # Обновляем финальный профиль с учетом внесенных элементов
832
- for fert, data in self.results.items():
833
- for key, value in data.items():
834
- if key.startswith('внесет'):
835
- element = key.split(': ')[0].replace('внесет ', '')
836
- if element == 'NO3':
837
- element = 'N (NO3-)'
838
- elif element == 'NH4':
839
- element = 'N (NH4+)'
840
-
841
- if element in self.final_profile:
842
- self.final_profile[element] -= value
843
 
844
  def calculate_ec(self):
845
- return round(self.total_ppm / 700, 2)
 
846
 
847
  def print_report(self):
848
  print("\n" + "="*60)
849
  print("ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА (ИТОГО):")
850
  print("="*60)
851
- table = [[el, round(val, 1)] for el, val in self.profile.items()]
852
  print(tabulate(table, headers=["Элемент", "ppm"]))
853
 
854
  print("\nИсходный расчёт азота:")
855
- for form, value in self.initial_n_profile.items():
856
- print(f" {form}: {value} ppm")
857
 
858
  print("\n" + "="*60)
859
  print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
860
  print("="*60)
861
- print(f"Общая концентрация: {round(self.total_ppm, 1)} ppm")
862
  print(f"EC: {self.calculate_ec()} mS/cm")
863
 
864
  print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
865
  fert_table = []
866
  for fert, data in self.results.items():
867
- details = [f"+{k}: {v} ppm" for k, v in data.items() if k.startswith('внесет')]
868
  fert_table.append([
869
  fert,
870
- f"{data['граммы']} г",
871
- f"{data['миллиграммы']} мг",
872
- "\n".join(details)
873
  ])
874
  print(tabulate(fert_table, headers=["Удобрение", "Граммы", "Миллиграммы", "Добавит"]))
875
 
876
  print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
877
- deficit = {k: round(abs(v), 1) for k, v in self.final_profile.items() if abs(v) > 0.1}
 
 
 
 
878
  if deficit:
879
  for el, val in deficit.items():
880
  print(f" {el}: {val} ppm")
@@ -888,5 +843,6 @@ if __name__ == "__main__":
888
 
889
 
890
 
 
891
  if __name__ == '__main__':
892
  app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))
 
678
 
679
 
680
 
 
681
  from tabulate import tabulate
682
 
683
+ # Константы
684
+ TOTAL_NITROGEN = 125
685
+ NO3_RATIO = 8.00
686
+ NH4_RATIO = 1.00
687
+ VOLUME_LITERS = 100
688
 
689
+ # Целевые значения
690
  BASE_PROFILE = {
691
  'P': 31.000,
692
  'K': 210.000,
 
697
  'N (NH4+)': 0
698
  }
699
 
 
700
  FERTILIZERS = {
701
  "Кальциевая селитра": {"N (NO3-)": 0.118, "Ca": 0.169},
702
  "Калий азотнокислый": {"N (NO3-)": 0.138, "K": 0.387},
 
710
  def __init__(self, volume_liters=1.0):
711
  self.volume = volume_liters
712
  self.results = {}
713
+ self.target_profile = BASE_PROFILE.copy()
714
+ self.actual_profile = {k: 0.0 for k in BASE_PROFILE}
715
  self.fertilizers = FERTILIZERS
716
+
717
+ # Расчёт азота
 
718
  total_parts = NO3_RATIO + NH4_RATIO
719
+ self.target_profile['N (NO3-)'] = TOTAL_NITROGEN * (NO3_RATIO / total_parts)
720
+ self.target_profile['N (NH4+)'] = TOTAL_NITROGEN * (NH4_RATIO / total_parts)
721
  self.initial_n_profile = {
722
+ "NO3-": self.target_profile['N (NO3-)'],
723
+ "NH4+": self.target_profile['N (NH4+)']
724
  }
725
 
726
  def calculate(self):
727
+ self._apply("Сульфат магния", "Mg", 24.0)
728
+ self._apply("Кальциевая селитра", "Ca", 84.0)
729
+ self._apply("Калий фосфорнокислый", "P", 31.0)
730
+ self._apply("Аммоний азотнокислый", "N (NH4+)", self.target_profile['N (NH4+)'])
731
+ self._apply_k_sulfate()
732
+ self._apply_k_nitrate()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
733
  return self.results
734
 
735
+ def _apply(self, fert_name, main_element, required_ppm):
736
+ content = self.fertilizers[fert_name][main_element]
737
+ grams = required_ppm * self.volume / (content * 1000)
738
+ result = {
 
 
 
 
 
 
 
 
 
739
  'граммы': round(grams, 3),
740
+ 'миллиграммы': int(grams * 1000)
 
741
  }
 
 
 
742
 
743
+ for element, percent in self.fertilizers[fert_name].items():
744
+ added_ppm = grams * percent * 1000 / self.volume
745
+ result[f'внесет {self._label(element)}'] = round(added_ppm, 1)
746
+ self.actual_profile[element] += added_ppm
 
 
 
 
 
 
 
 
747
 
748
+ self.results[fert_name] = result
749
+
750
+ def _apply_k_sulfate(self):
751
+ fert = "Калий сернокислый"
752
+ k_def = self.target_profile['K'] - self.actual_profile['K']
753
+ s_def = self.target_profile['S'] - self.actual_profile['S']
754
+ k_content = self.fertilizers[fert]["K"]
755
+ s_content = self.fertilizers[fert]["S"]
756
+
757
+ grams_k = k_def * self.volume / (k_content * 1000) if k_content else 0
758
+ grams_s = s_def * self.volume / (s_content * 1000) if s_content else 0
759
+ grams = max(grams_k, grams_s)
760
+
761
+ result = {
762
  'граммы': round(grams, 3),
763
+ 'миллиграммы': int(grams * 1000)
 
 
764
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
765
 
766
+ for el in ["K", "S"]:
767
+ ppm = grams * self.fertilizers[fert][el] * 1000 / self.volume
768
+ result[f"внесет {el}"] = round(ppm, 1)
769
+ self.actual_profile[el] += ppm
770
+
771
+ self.results[fert] = result
772
+
773
+ def _apply_k_nitrate(self):
774
+ fert = "Калий азотнокислый"
775
+ k_def = self.target_profile['K'] - self.actual_profile['K']
776
+ k_content = self.fertilizers[fert]["K"]
777
+ grams = k_def * self.volume / (k_content * 1000)
778
+
779
+ result = {
780
  'граммы': round(grams, 3),
781
+ 'миллиграммы': int(grams * 1000)
 
 
782
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
783
 
784
+ for el in ["K", "N (NO3-)"]:
785
+ ppm = grams * self.fertilizers[fert][el] * 1000 / self.volume
786
+ result[f"внесет {self._label(el)}"] = round(ppm, 1)
787
+ self.actual_profile[el] += ppm
788
+
789
+ self.results[fert] = result
790
+
791
+ def _label(self, el):
792
+ return "NO3" if el == "N (NO3-)" else "NH4" if el == "N (NH4+)" else el
 
 
 
 
793
 
794
  def calculate_ec(self):
795
+ total_ppm = sum(self.target_profile.values())
796
+ return round(total_ppm / 700, 2)
797
 
798
  def print_report(self):
799
  print("\n" + "="*60)
800
  print("ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА (ИТОГО):")
801
  print("="*60)
802
+ table = [[el, round(self.actual_profile[el], 1)] for el in self.actual_profile]
803
  print(tabulate(table, headers=["Элемент", "ppm"]))
804
 
805
  print("\nИсходный расчёт азота:")
806
+ for form, val in self.initial_n_profile.items():
807
+ print(f" {form}: {round(val, 1)} ppm")
808
 
809
  print("\n" + "="*60)
810
  print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
811
  print("="*60)
812
+ print(f"Общая концентрация: {round(sum(self.target_profile.values()), 1)} ppm")
813
  print(f"EC: {self.calculate_ec()} mS/cm")
814
 
815
  print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
816
  fert_table = []
817
  for fert, data in self.results.items():
818
+ adds = [f"+{k}: {v} ppm" for k, v in data.items() if k.startswith('внесет')]
819
  fert_table.append([
820
  fert,
821
+ data['граммы'],
822
+ data['миллиграммы'],
823
+ "\n".join(adds)
824
  ])
825
  print(tabulate(fert_table, headers=["Удобрение", "Граммы", "Миллиграммы", "Добавит"]))
826
 
827
  print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
828
+ deficit = {
829
+ k: round(self.target_profile[k] - self.actual_profile[k], 1)
830
+ for k in self.target_profile
831
+ if abs(self.target_profile[k] - self.actual_profile[k]) > 0.1
832
+ }
833
  if deficit:
834
  for el, val in deficit.items():
835
  print(f" {el}: {val} ppm")
 
843
 
844
 
845
 
846
+
847
  if __name__ == '__main__':
848
  app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))