DmitrMakeev commited on
Commit
034da28
·
verified ·
1 Parent(s): 7bd68c6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -192
app.py CHANGED
@@ -687,9 +687,9 @@ from tabulate import tabulate
687
 
688
  # Константы для расчёта
689
  TOTAL_NITROGEN = 125 # ppm
690
- NO3_RATIO = 8.00 # Доля нитратного азота (можно задавать 1.23, 5.67 и т.д.)
691
- NH4_RATIO = 1.00 # Доля аммонийного азота
692
- VOLUME_LITERS = 10 # Объём раствора
693
 
694
  # Базовый профиль (без азота)
695
  BASE_PROFILE = {
@@ -700,150 +700,91 @@ BASE_PROFILE = {
700
  'S': 137.397
701
  }
702
 
703
- # База данных удобрений
704
- fertilizers_db = {
705
  "Кальциевая селитра": {
706
- "N (NO3-)": 0.118,
707
- "Ca": 0.169,
708
  },
709
  "Калий азотнокислый": {
710
- "N (NO3-)": 0.138,
711
- "K": 0.387,
712
  },
713
  "Калий сернокислый": {
714
- "K": 0.448,
715
- "S": 0.184,
716
  },
717
  "Аммоний азотнокислый": {
718
- "N (NO3-)": 0.175,
719
- "N (NH4+)": 0.175,
720
  },
721
  "Сульфат магния": {
722
- "Mg": 0.098,
723
- "S": 0.13,
724
  },
725
  "Монофосфат калия": {
726
- "P": 0.227,
727
- "K": 0.287,
 
 
728
  }
729
  }
730
 
731
  class NutrientCalculator:
732
- def __init__(self, volume_liters=1.0):
 
 
 
 
 
733
  self.volume = volume_liters
734
  self.results = {}
735
  self.final_profile = {}
736
  self.total_ppm = 0
737
  self.calculated_profile = {}
738
-
739
- def calculate_nitrogen(self, total_n, no3_ratio, nh4_ratio):
740
- """Расчёт распределения азота по формам с точными соотношениями"""
741
- total_parts = no3_ratio + nh4_ratio
742
- no3 = total_n * (no3_ratio / total_parts)
743
- nh4 = total_n * (nh4_ratio / total_parts)
744
 
745
- self.calculated_profile = {
746
- 'N (NO3-)': round(no3, 2),
747
- 'N (NH4+)': round(nh4, 2),
748
- **BASE_PROFILE
749
- }
750
- return self.calculated_profile
751
-
752
- def calculate(self, total_n, no3_ratio, nh4_ratio):
753
- """Основной расчёт питательного раствора"""
754
- # Сначала рассчитываем азот
755
- profile = self.calculate_nitrogen(total_n, no3_ratio, nh4_ratio)
756
- self.final_profile = profile.copy()
757
- self.total_ppm = total_n + sum(BASE_PROFILE.values())
758
-
759
- # Расчёт удобрений
760
- self._apply_magnesium_sulfate()
761
- self._apply_calcium_nitrate()
762
- self._apply_mkp()
763
- self._apply_potassium_fertilizers()
764
- self._apply_ammonium_nitrate()
765
- return self.results
766
-
767
- def _apply_fertilizer(self, fert_name, grams, additions):
768
- """Добавление удобрения в результаты"""
769
- self.results[fert_name] = {
770
- 'граммы': round(grams, 3),
771
- 'миллиграммы': int(grams * 1000),
772
- **additions
773
  }
 
 
 
 
 
774
 
775
- def _apply_magnesium_sulfate(self):
776
- """Расчёт сульфата магния"""
777
- mg_need = self.final_profile['Mg']
778
- mg_content = fertilizers_db["Сульфат магния"]["Mg"]
779
- grams = (mg_need * self.volume) / (mg_content * 1000)
780
- added_s = grams * fertilizers_db["Сульфат магния"]["S"] * 1000 / self.volume
781
-
782
- self.final_profile['S'] -= added_s
783
- self._apply_fertilizer(
784
- "Сульфат магния",
785
- grams,
786
- {'внесет S': round(added_s, 2)}
787
- )
788
- self.final_profile['Mg'] = 0
789
-
790
- def _apply_calcium_nitrate(self):
791
- ca_need = self.final_profile['Ca']
792
- ca_content = fertilizers_db["Кальциевая селитра"]["Ca"]
793
- grams = (ca_need * self.volume) / (ca_content * 1000)
794
- added_n = grams * fertilizers_db["Кальциевая селитра"]["N (NO3-)"] * 1000 / self.volume
795
-
796
- self.final_profile['N (NO3-)'] -= added_n
797
- self._apply_fertilizer(
798
- "Кальциевая селитра",
799
- grams,
800
- {'внесет NO3': round(added_n, 2)}
801
- )
802
- self.final_profile['Ca'] = 0
803
-
804
- def _apply_mkp(self):
805
- p_need = self.final_profile['P']
806
- p_content = fertilizers_db["Монофосфат калия"]["P"]
807
- grams = (p_need * self.volume) / (p_content * 1000)
808
- added_k = grams * fertilizers_db["Монофосфат калия"]["K"] * 1000 / self.volume
809
-
810
- self.final_profile['K'] -= added_k
811
- self._apply_fertilizer(
812
- "Монофосфат калия",
813
- grams,
814
- {'внесет K': round(added_k, 2)}
815
- )
816
- self.final_profile['P'] = 0
817
 
818
  def _apply_potassium_fertilizers(self):
819
  k_need = self.final_profile['K']
820
  if k_need <= 0:
821
  return
822
 
823
- s_deficit = max(0, self.final_profile['S'])
824
- if s_deficit > 0:
825
- s_content = fertilizers_db["Калий сернокислый"]["S"]
826
- k2so4_grams = (s_deficit * self.volume) / (s_content * 1000)
827
- added_k = k2so4_grams * fertilizers_db["Калий сернокислый"]["K"] * 1000 / self.volume
828
-
829
- if added_k > k_need:
830
- k2so4_grams = (k_need * self.volume) / (fertilizers_db["Калий сернокислый"]["K"] * 1000)
831
- added_k = k_need
832
- added_s = k2so4_grams * fertilizers_db["Калий сернокислый"]["S"] * 1000 / self.volume
833
- else:
834
- added_s = s_deficit
835
-
836
- self._apply_fertilizer("Калий сернокислый", k2so4_grams, {
837
- 'внесет K': round(added_k, 2),
838
- 'внесет S': round(added_s, 2)
839
- })
840
- self.final_profile['K'] -= added_k
841
- self.final_profile['S'] -= added_s
842
- k_need = self.final_profile['K']
843
-
844
- if k_need > 0:
845
- kno3_grams = (k_need * self.volume) / (fertilizers_db["Калий азотнокислый"]["K"] * 1000)
846
- added_n = kno3_grams * fertilizers_db["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
 
 
 
847
 
848
  self._apply_fertilizer(
849
  "Калий азотнокислый",
@@ -853,81 +794,21 @@ class NutrientCalculator:
853
  self.final_profile['K'] = 0
854
  self.final_profile['N (NO3-)'] -= added_n
855
 
856
- def _apply_ammonium_nitrate(self):
857
- nh4_need = self.final_profile['N (NH4+)']
858
- if nh4_need <= 0:
859
- return
860
- nh4_content = fertilizers_db["Аммоний азотнокислый"]["N (NH4+)"]
861
- grams = (nh4_need * self.volume) / (nh4_content * 1000)
862
- added_n = grams * fertilizers_db["Аммоний азотнокислый"]["N (NO3-)"] * 1000 / self.volume
863
-
864
- self.final_profile['N (NO3-)'] -= added_n
865
- self._apply_fertilizer(
866
- "Аммоний азотнокислый",
867
- grams,
868
- {'внесет NO3': round(added_n, 2)}
869
- )
870
- self.final_profile['N (NH4+)'] = 0
871
-
872
- def calculate_ec(self):
873
- """Расчёт электропроводимости"""
874
- return round(self.total_ppm / 700, 3)
875
-
876
- def print_report(self):
877
- """Вывод результатов расчёта"""
878
- # Выводим расчётный профиль после вычисления азота
879
- print("\n" + "="*60)
880
- print("РАСЧЁТНЫЙ ПРОФИЛЬ (после расчёта азота):")
881
- print("="*60)
882
- print(f"Соотношение NO3:NH4 = {NO3_RATIO:.2f}:{NH4_RATIO:.2f}")
883
-
884
- profile_table = [
885
- [element, f"{value:.2f}"]
886
- for element, value in self.calculated_profile.items()
887
- ]
888
- print(tabulate(profile_table, headers=["Элемент", "Концентрация ppm"]))
889
-
890
- # Выводим результаты расчёта удобрений
891
- print("\n" + "="*60)
892
- print(f"РЕЗУЛЬТАТЫ РАСЧЁТА ДЛЯ {self.volume} ЛИТРОВ")
893
- print("="*60)
894
- print(f"Общая концентрация: {self.total_ppm:.2f} ppm")
895
- print(f"EC: {self.calculate_ec()} mS/cm")
896
-
897
- print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
898
- fert_table = []
899
- for fert, data in self.results.items():
900
- details = [
901
- f"+{k}: {v:.2f} ppm"
902
- for k, v in data.items()
903
- if k.startswith('внесет')
904
- ]
905
- fert_table.append([
906
- fert,
907
- f"{data['граммы']:.3f} г",
908
- f"{data['миллиграммы']} мг",
909
- "\n".join(details)
910
- ])
911
- print(tabulate(fert_table,
912
- headers=["Удобрение", "Граммы", "Миллиграммы", "Добавит"]))
913
-
914
- print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
915
- deficit = {
916
- k: round(v, 2)
917
- for k, v in self.final_profile.items()
918
- if v > 0.01 # Более точный порог
919
- }
920
- if deficit:
921
- for el, val in deficit.items():
922
- print(f" {el}: {val:.2f} ppm")
923
- else:
924
- print(" Все элементы покрыты полностью")
925
-
926
-
927
 
928
- calc = NutrientCalculator(volume_liters=VOLUME_LITERS)
929
- calc.calculate(TOTAL_NITROGEN, NO3_RATIO, NH4_RATIO)
930
- calc.print_report()
 
931
 
932
 
933
 
 
687
 
688
  # Константы для расчёта
689
  TOTAL_NITROGEN = 125 # ppm
690
+ NO3_RATIO = 8.00 # Доля нитратного азота
691
+ NH4_RATIO = 1.00 # Доля аммонийного азота
692
+ VOLUME_LITERS = 10 # Объём раствора
693
 
694
  # Базовый профиль (без азота)
695
  BASE_PROFILE = {
 
700
  'S': 137.397
701
  }
702
 
703
+ # Полная база всех возможных удобрений
704
+ ALL_FERTILIZERS = {
705
  "Кальциевая селитра": {
706
+ "N (NO3-)": 0.118, "Ca": 0.169
 
707
  },
708
  "Калий азотнокислый": {
709
+ "N (NO3-)": 0.138, "K": 0.387
 
710
  },
711
  "Калий сернокислый": {
712
+ "K": 0.448, "S": 0.184
 
713
  },
714
  "Аммоний азотнокислый": {
715
+ "N (NO3-)": 0.175, "N (NH4+)": 0.175
 
716
  },
717
  "Сульфат магния": {
718
+ "Mg": 0.098, "S": 0.13
 
719
  },
720
  "Монофосфат калия": {
721
+ "P": 0.227, "K": 0.287
722
+ },
723
+ "Сульфат калия": {
724
+ "K": 0.448, "S": 0.184 # Альтернатива калию сернокислому
725
  }
726
  }
727
 
728
  class NutrientCalculator:
729
+ def __init__(self, volume_liters=1.0, use_k2so4=True, use_kno3=True):
730
+ """
731
+ :param volume_liters: Объём раствора
732
+ :param use_k2so4: Использовать калий сернокислый (True/False)
733
+ :param use_kno3: Использовать калий азотнокислый (True/False)
734
+ """
735
  self.volume = volume_liters
736
  self.results = {}
737
  self.final_profile = {}
738
  self.total_ppm = 0
739
  self.calculated_profile = {}
 
 
 
 
 
 
740
 
741
+ # Формируем активные удобрения на основе выбора
742
+ self.fertilizers_db = {
743
+ "Кальциевая селитра": ALL_FERTILIZERS["Кальциевая селитра"],
744
+ "Аммоний азотнокислый": ALL_FERTILIZERS["Аммоний азотнокислый"],
745
+ "Сульфат магния": ALL_FERTILIZERS["Сульфат магния"],
746
+ "Монофосфат калия": ALL_FERTILIZERS["Монофосфат калия"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747
  }
748
+
749
+ if use_k2so4:
750
+ self.fertilizers_db["Калий сернокислый"] = ALL_FERTILIZERS["Калий сернокислый"]
751
+ if use_kno3:
752
+ self.fertilizers_db["Калий азотнокислый"] = ALL_FERTILIZERS["Калий азотнокислый"]
753
 
754
+ # ... (остальные методы класса остаются без изменений)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
755
 
756
  def _apply_potassium_fertilizers(self):
757
  k_need = self.final_profile['K']
758
  if k_need <= 0:
759
  return
760
 
761
+ # Вариант 1: Если есть калий сернокислый
762
+ if "Калий сернокислый" in self.fertilizers_db:
763
+ s_deficit = max(0, self.final_profile['S'])
764
+ if s_deficit > 0:
765
+ s_content = self.fertilizers_db["Калий сернокислый"]["S"]
766
+ k2so4_grams = (s_deficit * self.volume) / (s_content * 1000)
767
+ added_k = k2so4_grams * self.fertilizers_db["Калий сернокислый"]["K"] * 1000 / self.volume
768
+
769
+ if added_k > k_need:
770
+ k2so4_grams = (k_need * self.volume) / (self.fertilizers_db["Калий сернокислый"]["K"] * 1000)
771
+ added_k = k_need
772
+ added_s = k2so4_grams * self.fertilizers_db["Калий сернокислый"]["S"] * 1000 / self.volume
773
+ else:
774
+ added_s = s_deficit
775
+
776
+ self._apply_fertilizer("Калий сернокислый", k2so4_grams, {
777
+ 'внесет K': round(added_k, 2),
778
+ 'внесет S': round(added_s, 2)
779
+ })
780
+ self.final_profile['K'] -= added_k
781
+ self.final_profile['S'] -= added_s
782
+ k_need = self.final_profile['K']
783
+
784
+ # Вариант 2: Если есть только калий азотнокислый
785
+ if k_need > 0 and "Калий азотнокислый" in self.fertilizers_db:
786
+ kno3_grams = (k_need * self.volume) / (self.fertilizers_db["Калий азотнокислый"]["K"] * 1000)
787
+ added_n = kno3_grams * self.fertilizers_db["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
788
 
789
  self._apply_fertilizer(
790
  "Калий азотнокислый",
 
794
  self.final_profile['K'] = 0
795
  self.final_profile['N (NO3-)'] -= added_n
796
 
797
+ # Если остался дефицит и нет подходящих удобрений
798
+ if k_need > 0:
799
+ print(f" Внимание: Не удалось полностью покрыть дефицит K ({k_need:.2f} ppm)")
800
+
801
+ # Пример использования
802
+ if __name__ == "__main__":
803
+ # Вариант 1: С калием сернокислым
804
+ calc_with_k2so4 = NutrientCalculator(volume_liters=10, use_k2so4=True, use_kno3=False)
805
+ calc_with_k2so4.calculate(TOTAL_NITROGEN, NO3_RATIO, NH4_RATIO)
806
+ calc_with_k2so4.print_report()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
807
 
808
+ # Вариант 2: С калием азотнокислым
809
+ calc_with_kno3 = NutrientCalculator(volume_liters=10, use_k2so4=False, use_kno3=True)
810
+ calc_with_kno3.calculate(TOTAL_NITROGEN, NO3_RATIO, NH4_RATIO)
811
+ calc_with_kno3.print_report()
812
 
813
 
814