DmitrMakeev commited on
Commit
7bd2372
·
verified ·
1 Parent(s): 03d2b53

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -154
app.py CHANGED
@@ -702,149 +702,105 @@ BASE_PROFILE = {
702
  'N (NH4+)': 0
703
  }
704
 
705
- # Полная база всех удобрений (7 удобрений)
706
- ALL_FERTILIZERS = {
707
- "Кальциевая селитра": {
708
- "N (NO3-)": 0.118, "Ca": 0.169
709
- },
710
- "Калий азотнокислый": {
711
- "N (NO3-)": 0.138, "K": 0.387
712
- },
713
- "Калий сернокислый": {
714
- "K": 0.448, "S": 0.184
715
- },
716
- "Аммоний азотнокислый": {
717
- "N (NO3-)": 0.175, "N (NH4+)": 0.175
718
- },
719
- "Сульфат магния": {
720
- "Mg": 0.098, "S": 0.13
721
- },
722
- "Калий фосфорнокислый": {
723
- "P": 0.228, "K": 0.287
724
- },
725
- "Монофосфат калия": {
726
- "P": 0.228, "K": 0.287
727
- }
728
  }
729
 
730
  class NutrientCalculator:
731
  def __init__(self, volume_liters=1.0):
732
  self.volume = volume_liters
733
  self.results = {}
734
- self.final_profile = BASE_PROFILE.copy()
735
  self.total_ppm = sum(BASE_PROFILE.values()) + TOTAL_NITROGEN
736
- self.fertilizers_db = ALL_FERTILIZERS
737
- self.target_nitrogen = {
738
- 'NO3': TOTAL_NITROGEN * (NO3_RATIO / (NO3_RATIO + NH4_RATIO)),
739
- 'NH4': TOTAL_NITROGEN * (NH4_RATIO / (NO3_RATIO + NH4_RATIO))
740
- }
741
 
742
  def calculate(self):
743
- # 1. Вносим удобрения в строгом порядке
744
- self._apply_magnesium_sulfate()
745
- self._apply_calcium_nitrate()
746
- self._apply_potassium_phosphate()
747
- self._apply_ammonium_nitrate()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
748
  self._apply_potassium_sulfate()
749
- self._apply_potassium_nitrate()
750
- self._apply_monopotassium_phosphate()
751
 
752
- # 2. Корректируем отрицательные значения
753
- self._adjust_negative_values()
754
 
755
- # 3. Пересчитываем фактическое содержание азота
756
- self._recalculate_actual_nitrogen()
757
 
758
  return self.results
759
 
760
- def _apply_fertilizer(self, fert_name, grams, additions):
761
- self.results[fert_name] = {
 
 
 
 
 
 
 
 
 
 
 
 
 
762
  'граммы': round(grams, 3),
763
  'миллиграммы': int(grams * 1000),
 
764
  }
765
- self.results[fert_name].update(additions)
766
-
767
- def _adjust_negative_values(self):
768
- for element in self.final_profile:
769
- if self.final_profile[element] < 0:
770
- self.final_profile[element] = 0
771
-
772
- def _recalculate_actual_nitrogen(self):
773
- # Пересчитываем фактическое содержание азота на основе внесенных удобрений
774
- no3_added = 0
775
- nh4_added = 0
776
-
777
- for fert in self.results.values():
778
- if 'внесет NO3' in fert:
779
- no3_added += fert['внесет NO3']
780
- if 'внесет NH4' in fert:
781
- nh4_added += fert['внесет NH4']
782
-
783
- self.final_profile['N (NO3-)'] = no3_added
784
- self.final_profile['N (NH4+)'] = nh4_added
785
-
786
- def _apply_magnesium_sulfate(self):
787
- mg_need = self.final_profile['Mg']
788
- if mg_need <= 0:
789
- return
790
-
791
- mg_content = self.fertilizers_db["Сульфат магния"]["Mg"]
792
- grams = (mg_need * self.volume) / (mg_content * 1000)
793
- added_s = grams * self.fertilizers_db["Сульфат магния"]["S"] * 1000 / self.volume
794
-
795
- self.final_profile['S'] -= added_s
796
- self._apply_fertilizer("Сульфат магния", grams, {'внесет S': round(added_s, 1)})
797
- self.final_profile['Mg'] = 0
798
-
799
- def _apply_calcium_nitrate(self):
800
- ca_need = self.final_profile['Ca']
801
- if ca_need <= 0:
802
- return
803
-
804
- ca_content = self.fertilizers_db["Кальциевая селитра"]["Ca"]
805
- grams = (ca_need * self.volume) / (ca_content * 1000)
806
- added_n = grams * self.fertilizers_db["Кальциевая селитра"]["N (NO3-)"] * 1000 / self.volume
807
-
808
- self._apply_fertilizer("Кальциевая селитра", grams, {'внесет NO3': round(added_n, 1)})
809
- self.final_profile['Ca'] = 0
810
-
811
- def _apply_potassium_phosphate(self):
812
- p_need = self.final_profile['P']
813
- if p_need <= 0:
814
- return
815
-
816
- p_content = self.fertilizers_db["Калий фосфорнокислый"]["P"]
817
- grams = (p_need * self.volume) / (p_content * 1000)
818
- added_k = grams * self.fertilizers_db["Калий фосфорнокислый"]["K"] * 1000 / self.volume
819
-
820
- self.final_profile['K'] -= added_k
821
- self._apply_fertilizer("Калий фосфорнокислый", grams, {'внесет K': round(added_k, 1)})
822
- self.final_profile['P'] = 0
823
-
824
- def _apply_ammonium_nitrate(self):
825
- nh4_need = self.target_nitrogen['NH4']
826
- if nh4_need <= 0:
827
- return
828
-
829
- nh4_content = self.fertilizers_db["Аммоний азотнокислый"]["N (NH4+)"]
830
- grams = (nh4_need * self.volume) / (nh4_content * 1000)
831
- added_n = grams * self.fertilizers_db["Аммоний азотнокислый"]["N (NO3-)"] * 1000 / self.volume
832
-
833
- self._apply_fertilizer("Аммоний азотнокислый", grams, {
834
- 'внесет NO3': round(added_n, 1),
835
- 'внесет NH4': round(nh4_need, 1)
836
- })
837
 
838
  def _apply_potassium_sulfate(self):
839
- k_need = self.final_profile['K']
840
- s_need = self.final_profile['S']
841
 
842
  if k_need <= 0 or s_need <= 0:
843
  return
844
 
845
- k_content = self.fertilizers_db["Калий сернокислый"]["K"]
846
- s_content = self.fertilizers_db["Калий сернокислый"]["S"]
847
 
 
848
  grams = min(
849
  (k_need * self.volume) / (k_content * 1000),
850
  (s_need * self.volume) / (s_content * 1000)
@@ -853,63 +809,62 @@ class NutrientCalculator:
853
  added_k = grams * k_content * 1000 / self.volume
854
  added_s = grams * s_content * 1000 / self.volume
855
 
856
- self.final_profile['K'] -= added_k
857
- self.final_profile['S'] -= added_s
858
- self._apply_fertilizer("Калий сернокислый", grams, {
859
- 'внесет K': round(added_k, 2),
860
- 'внесет S': round(added_s, 2)
861
- })
 
 
862
 
863
  def _apply_potassium_nitrate(self):
864
- k_need = self.final_profile['K']
865
  if k_need <= 0:
866
  return
867
 
868
- k_content = self.fertilizers_db["Калий азотнокислый"]["K"]
869
  grams = (k_need * self.volume) / (k_content * 1000)
870
- added_n = grams * self.fertilizers_db["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
871
-
872
- self.final_profile['K'] = 0
873
- self._apply_fertilizer("Калий азотнокислый", grams, {'внесет NO3': round(added_n, 2)})
874
 
875
- def _apply_monopotassium_phosphate(self):
876
- # Добавляем дополнительное фосфорное удобрение для полного покрытия
877
- p_need = self.final_profile['P']
878
- if p_need <= 0:
879
- return
880
-
881
- p_content = self.fertilizers_db["Монофосфат калия"]["P"]
882
- grams = (p_need * self.volume) / (p_content * 1000)
883
- added_k = grams * self.fertilizers_db["Монофосфат калия"]["K"] * 1000 / self.volume
884
 
885
- self.final_profile['K'] -= added_k
886
- self._apply_fertilizer("Монофосфат калия", grams, {
887
- 'внесет P': round(p_need, 1),
888
- 'внесет K': round(added_k, 1)
889
- })
890
- self.final_profile['P'] = 0
 
 
 
 
 
 
 
891
 
892
  def calculate_ec(self):
893
  return round(self.total_ppm / 700, 2)
894
 
895
  def print_report(self):
896
  print("\n" + "="*60)
897
- print("ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА (ПЕРЕСЧИТАННЫЙ):")
898
  print("="*60)
899
- table = [[el, round(val, 1)] for el, val in self.final_profile.items()]
900
  print(tabulate(table, headers=["Элемент", "ppm"]))
901
 
902
- print("\nЦелевые значения азота:")
903
- print(f" N (NO3-): {round(self.target_nitrogen['NO3'], 1)} ppm")
904
- print(f" N (NH4+): {round(self.target_nitrogen['NH4'], 1)} ppm")
905
-
906
  print("\n" + "="*60)
907
  print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
908
  print("="*60)
909
  print(f"Общая концентрация: {round(self.total_ppm, 1)} ppm")
910
  print(f"EC: {self.calculate_ec()} mS/cm")
911
 
912
- print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
913
  fert_table = []
914
  for fert, data in self.results.items():
915
  details = [f"+{k}: {v} ppm" for k, v in data.items() if k.startswith('внесет')]
@@ -922,10 +877,10 @@ class NutrientCalculator:
922
  print(tabulate(fert_table, headers=["Удобрение", "Граммы", "Миллиграммы", "Добавит"]))
923
 
924
  print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
925
- deficit = {k: v for k, v in self.final_profile.items() if v > 0.1}
926
  if deficit:
927
  for el, val in deficit.items():
928
- print(f" {el}: {round(val, 1)} ppm")
929
  else:
930
  print(" Все элементы покрыты полностью")
931
 
 
702
  'N (NH4+)': 0
703
  }
704
 
705
+ # База удобрений (6 удобрений)
706
+ FERTILIZERS = {
707
+ "Кальциевая селитра": {"N (NO3-)": 0.118, "Ca": 0.169},
708
+ "Калий азотнокислый": {"N (NO3-)": 0.138, "K": 0.387},
709
+ "Калий сернокислый": {"K": 0.448, "S": 0.184},
710
+ "Аммоний азотнокислый": {"N (NO3-)": 0.175, "N (NH4+)": 0.175},
711
+ "Сульфат магния": {"Mg": 0.098, "S": 0.13},
712
+ "Калий фосфорнокислый": {"P": 0.228, "K": 0.287}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
713
  }
714
 
715
  class NutrientCalculator:
716
  def __init__(self, volume_liters=1.0):
717
  self.volume = volume_liters
718
  self.results = {}
719
+ self.profile = BASE_PROFILE.copy()
720
  self.total_ppm = sum(BASE_PROFILE.values()) + TOTAL_NITROGEN
721
+ self.fertilizers = FERTILIZERS
722
+
723
+ # Целевые значения азота
724
+ self.target_no3 = TOTAL_NITROGEN * (NO3_RATIO / (NO3_RATIO + NH4_RATIO))
725
+ self.target_nh4 = TOTAL_NITROGEN * (NH4_RATIO / (NO3_RATIO + NH4_RATIO))
726
 
727
  def calculate(self):
728
+ # 1. Вносим сульфат магния (покрываем Mg)
729
+ self._apply_fertilizer(
730
+ "Сульфат магния",
731
+ self.profile['Mg'],
732
+ "Mg",
733
+ {"S": "внесет S"}
734
+ )
735
+
736
+ # 2. Вносим кальциевую селитру (покрываем Ca)
737
+ self._apply_fertilizer(
738
+ "Кальциевая селитра",
739
+ self.profile['Ca'],
740
+ "Ca",
741
+ {"N (NO3-)": "внесет NO3"}
742
+ )
743
+
744
+ # 3. Вносим калий фосфорнокислый (покрываем P)
745
+ self._apply_fertilizer(
746
+ "Калий фосфорнокислый",
747
+ self.profile['P'],
748
+ "P",
749
+ {"K": "внесет K"}
750
+ )
751
+
752
+ # 4. Вносим аммоний азотнокислый (покрываем NH4)
753
+ nh4_needed = self.target_nh4
754
+ if nh4_needed > 0:
755
+ self._apply_fertilizer(
756
+ "Аммоний азотнокислый",
757
+ nh4_needed,
758
+ "N (NH4+)",
759
+ {"N (NO3-)": "внесет NO3"}
760
+ )
761
+
762
+ # 5. Вносим калий сернокислый (покрываем K и S)
763
  self._apply_potassium_sulfate()
 
 
764
 
765
+ # 6. Вносим калий азотнокислый (добираем K)
766
+ self._apply_potassium_nitrate()
767
 
768
+ # Пересчитываем фактическое содержание азота
769
+ self._recalculate_nitrogen()
770
 
771
  return self.results
772
 
773
+ def _apply_fertilizer(self, name, need, main_element, additions):
774
+ if need <= 0:
775
+ return
776
+
777
+ content = self.fertilizers[name][main_element]
778
+ grams = (need * self.volume) / (content * 1000)
779
+
780
+ added = {}
781
+ for element, label in additions.items():
782
+ added_amount = grams * self.fertilizers[name][element] * 1000 / self.volume
783
+ added[label] = round(added_amount, 1)
784
+ self.profile[element] -= added_amount
785
+
786
+ self.profile[main_element] = 0
787
+ self.results[name] = {
788
  'граммы': round(grams, 3),
789
  'миллиграммы': int(grams * 1000),
790
+ **added
791
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
792
 
793
  def _apply_potassium_sulfate(self):
794
+ k_need = self.profile['K']
795
+ s_need = self.profile['S']
796
 
797
  if k_need <= 0 or s_need <= 0:
798
  return
799
 
800
+ k_content = self.fertilizers["Калий сернокислый"]["K"]
801
+ s_content = self.fertilizers["Калий сернокислый"]["S"]
802
 
803
+ # Рассчитываем максимально возможное внесение
804
  grams = min(
805
  (k_need * self.volume) / (k_content * 1000),
806
  (s_need * self.volume) / (s_content * 1000)
 
809
  added_k = grams * k_content * 1000 / self.volume
810
  added_s = grams * s_content * 1000 / self.volume
811
 
812
+ self.profile['K'] -= added_k
813
+ self.profile['S'] -= added_s
814
+ self.results["Калий сернокислый"] = {
815
+ 'граммы': round(grams, 3),
816
+ 'миллиграммы': int(grams * 1000),
817
+ 'внесет K': round(added_k, 1),
818
+ 'внесет S': round(added_s, 1)
819
+ }
820
 
821
  def _apply_potassium_nitrate(self):
822
+ k_need = self.profile['K']
823
  if k_need <= 0:
824
  return
825
 
826
+ k_content = self.fertilizers["Калий азотнокислый"]["K"]
827
  grams = (k_need * self.volume) / (k_content * 1000)
828
+ added_n = grams * self.fertilizers["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
 
 
 
829
 
830
+ self.profile['K'] = 0
831
+ self.results["Калий азотнокислый"] = {
832
+ 'граммы': round(grams, 3),
833
+ 'миллиграммы': int(grams * 1000),
834
+ 'внесет NO3': round(added_n, 1)
835
+ }
 
 
 
836
 
837
+ def _recalculate_nitrogen(self):
838
+ # Считаем фактически внесенный азот
839
+ no3 = 0
840
+ nh4 = 0
841
+
842
+ for fert in self.results.values():
843
+ if 'внесет NO3' in fert:
844
+ no3 += fert['внесет NO3']
845
+ if 'внесет NH4' in fert:
846
+ nh4 += fert['внесет NH4']
847
+
848
+ self.profile['N (NO3-)'] = no3
849
+ self.profile['N (NH4+)'] = nh4
850
 
851
  def calculate_ec(self):
852
  return round(self.total_ppm / 700, 2)
853
 
854
  def print_report(self):
855
  print("\n" + "="*60)
856
+ print("ПРОФИЛЬ ПИТАТЕЛЬНОГО РАСТВОРА:")
857
  print("="*60)
858
+ table = [[el, round(val, 1)] for el, val in self.profile.items()]
859
  print(tabulate(table, headers=["Элемент", "ppm"]))
860
 
 
 
 
 
861
  print("\n" + "="*60)
862
  print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
863
  print("="*60)
864
  print(f"Общая концентрация: {round(self.total_ppm, 1)} ppm")
865
  print(f"EC: {self.calculate_ec()} mS/cm")
866
 
867
+ print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ (6 штук):")
868
  fert_table = []
869
  for fert, data in self.results.items():
870
  details = [f"+{k}: {v} ppm" for k, v in data.items() if k.startswith('внесет')]
 
877
  print(tabulate(fert_table, headers=["Удобрение", "Граммы", "Миллиграммы", "Добавит"]))
878
 
879
  print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
880
+ deficit = {k: round(v, 1) for k, v in self.profile.items() if v > 0.1}
881
  if deficit:
882
  for el, val in deficit.items():
883
+ print(f" {el}: {val} ppm")
884
  else:
885
  print(" Все элементы покрыты полностью")
886