DmitrMakeev commited on
Commit
aa339ab
·
verified ·
1 Parent(s): b2f2f8c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +133 -143
app.py CHANGED
@@ -14,6 +14,8 @@ from io import BytesIO
14
 
15
 
16
 
 
 
17
 
18
 
19
 
@@ -679,166 +681,154 @@ def view_image():
679
 
680
 
681
 
 
 
 
 
 
 
 
 
 
 
 
 
 
682
  fertilizers_db = {
683
- # Кальциевая селитра (Ca(NO3)2 · 4H2O - тетрагидрат)
684
  "Кальциевая селитра": {
685
- "N (NO3-)": 0.118, # 11.8% азота (правильно)
686
- "Ca": 0.169 # 16.9% кальция (правильно)
687
  },
688
-
689
- # Калий азотнокислый (KNO3)
690
  "Калий азотнокислый": {
691
- "N (NO3-)": 0.138, # 13.8% азота (правильно)
692
- "K": 0.387 # 38.7% калия (правильно)
693
  },
694
-
695
- # Аммоний азотнокислый (NH4NO3)
696
  "Аммоний азотнокислый": {
697
- "N (NO3-)": 0.175, # 17.5% нитратного азота
698
- "N (NH4+)": 0.175 # 17.5% аммонийного азота
699
  },
700
-
701
- # Сульфат магния (MgSO4 · 7H2O - гептагидрат)
702
  "Сульфат магния": {
703
- "Mg": 0.098, # 9.8% магния (правильно)
704
- "S": 0.13 # 13% серы (правильно)
705
  },
706
-
707
- # Монофосфат калия (KH2PO4)
708
  "Монофосфат калия": {
709
- "P": 0.227, # 22.7% фосфора (правильно)
710
- "K": 0.287 # 28.7% калия (правильно)
711
  }
712
  }
713
 
714
- class HydroCalculator:
715
  def __init__(self, volume_liters=1.0):
716
- self.volume = volume_liters
717
- self.fertilizers = []
718
-
719
- def add_fertilizer(self, name, grams):
720
- if name not in fertilizers_db:
721
- raise ValueError(f"Удобрение '{name}' не найдено в базе!")
722
- self.fertilizers.append((name, grams))
723
-
724
- def calculate_ppm(self):
725
- ppm = {}
726
- for name, grams in self.fertilizers:
727
- for element, ratio in fertilizers_db[name].items():
728
- ppm[element] = ppm.get(element, 0) + (grams * ratio * 1000) / (self.volume * 10)
729
- return ppm
730
-
731
- def calculate_ec(self):
732
- ppm = self.calculate_ppm()
733
- ec = 0.0
734
- EC_COEFFICIENTS = {
735
- 'N (NO3-)': 0.6,
736
- 'N (NH4+)': 0.4,
737
- 'K': 0.7,
738
- 'Ca': 0.75,
739
- 'Mg': 0.6,
740
- 'S': 0.3,
741
- 'P': 0.1,
742
- }
743
- for element, value in ppm.items():
744
- if element in EC_COEFFICIENTS:
745
- ec += value * EC_COEFFICIENTS[element]
746
- return ec / 100
747
-
748
- def calculate_ec_exact(self):
749
- MOLAR_MASSES = {
750
- 'NO3-': 62.0,
751
- 'NH4+': 18.0,
752
- 'K+': 39.1,
753
- 'Ca+2': 40.1,
754
- 'Mg+2': 24.3,
755
- 'SO4-2': 96.1,
756
- 'H2PO4-': 97.0,
757
- }
758
- ION_CONDUCTIVITY = {
759
- 'NO3-': 71.4,
760
- 'NH4+': 73.5,
761
- 'K+': 73.5,
762
- 'Ca+2': 119.0,
763
- 'Mg+2': 106.0,
764
- 'SO4-2': 160.0,
765
- 'H2PO4-': 33.0,
766
- }
767
- ELEMENT_TO_ION = {
768
- 'N (NO3-)': 'NO3-',
769
- 'N (NH4+)': 'NH4+',
770
- 'K': 'K+',
771
- 'Ca': 'Ca+2',
772
- 'Mg': 'Mg+2',
773
- 'S': 'SO4-2',
774
- 'P': 'H2PO4-',
775
- }
776
-
777
- ppm = self.calculate_ppm()
778
- ec = 0.0 # µS/cm
779
-
780
- for element, value in ppm.items():
781
- if element in ELEMENT_TO_ION:
782
- ion = ELEMENT_TO_ION[element]
783
- molar_mass = MOLAR_MASSES[ion]
784
- conductivity = ION_CONDUCTIVITY[ion]
785
- # ppm = mg/L mmol/L = (ppm / molar_mass)
786
- mmol_per_liter = value / molar_mass
787
- # µS/cm = mmol/L * µS·cm²/mmol
788
- ec += mmol_per_liter * conductivity
789
-
790
- return ec / 100 # переводим в mS/cm
791
-
792
- def print_report(self):
793
- ppm = self.calculate_ppm()
794
- ec_simple = self.calculate_ec()
795
- ec_exact = self.calculate_ec_exact()
796
-
797
- # Вывод основной таблицы элементов
798
- print("\n" + "="*50)
799
- print("ТАБЛИЦА КОНЦЕНТРАЦИЙ ЭЛЕМЕНТОВ")
800
- print("="*50)
801
- print("{:<15} {:>15} {:>15}".format("Элемент", "Конц. (ppm)", "Конц. (мг/л)"))
802
- print("-"*50)
803
- for element, value in sorted(ppm.items()):
804
- print("{:<15} {:>15.2f} {:>15.2f}".format(element, value, value))
805
- print("="*50)
806
-
807
- # Вывод данных по азоту
808
- print("\n" + "="*50)
809
- print("АНАЛИЗ АЗОТНЫХ СОЕДИНЕНИЙ")
810
- print("="*50)
811
- print(f"Общий азот (N): {ppm.get('N (NO3-)', 0) + ppm.get('N (NH4+)', 0):.2f} ppm")
812
- print(f"Нитратный азот (NO3-): {ppm.get('N (NO3-)', 0):.2f} ppm")
813
- print(f"Аммонийный азот (NH4+): {ppm.get('N (NH4+)', 0):.2f} ppm")
814
- print("="*50)
815
-
816
- # Вывод электропроводности
817
  print("\n" + "="*50)
818
- print("ЭЛЕКТРОПРОВОДНОСТЬ РАСТВОРА")
819
  print("="*50)
820
- print(f"EC: {ec_simple:.2f} mS/cm")
821
- print("="*50)
822
-
823
 
824
-
825
- # Пример использования с правильными названиями удобрений
826
- calc = HydroCalculator(10) # 10 литров раствора
827
-
828
- # Добавляем удобрения с правильными названиями и адекватными количествами
829
- calc.add_fertilizer("Кальциевая селитра", 5) # 10 г
830
- calc.add_fertilizer("Калий азотнокислый", 5) # 5 г
831
- calc.add_fertilizer("Аммоний азотнокислый", 5) # 3 г
832
-
833
- # Выводим полный отчёт
834
- calc.print_report()
835
-
836
- # Дополнительный вывод только NO3 и NH4
837
- ppm = calc.calculate_ppm()
838
- print("\nСодержание азота:")
839
- print(f"NO3-: {ppm.get('N (NO3-)', 0):.2f} ppm")
840
- print(f"NH4+: {ppm.get('N (NH4+)', 0):.2f} ppm")
841
-
 
 
 
 
 
 
842
 
843
 
844
 
 
14
 
15
 
16
 
17
+ import numpy as np
18
+ from tabulate import tabulate
19
 
20
 
21
 
 
681
 
682
 
683
 
684
+
685
+ # Профиль питательного раствора (ppm = мг/литр)
686
+ TOMATO_PROFILE = {
687
+ 'N (NO3-)': 200,
688
+ 'N (NH4+)': 20,
689
+ 'P': 50,
690
+ 'K': 350,
691
+ 'Mg': 50,
692
+ 'Ca': 200,
693
+ 'S': 100
694
+ }
695
+
696
+ # База данных удобрений (монокомпоненты)
697
  fertilizers_db = {
 
698
  "Кальциевая селитра": {
699
+ "N (NO3-)": 0.118, # 11.8% N
700
+ "Ca": 0.169 # 16.9% Ca
701
  },
 
 
702
  "Калий азотнокислый": {
703
+ "N (NO3-)": 0.138, # 13.8% N
704
+ "K": 0.387 # 38.7% K
705
  },
 
 
706
  "Аммоний азотнокислый": {
707
+ "N (NO3-)": 0.175, # 17.5% N
708
+ "N (NH4+)": 0.175 # 17.5% N
709
  },
 
 
710
  "Сульфат магния": {
711
+ "Mg": 0.098, # 9.8% Mg
712
+ "S": 0.13 # 13% S
713
  },
 
 
714
  "Монофосфат калия": {
715
+ "P": 0.227, # 22.7% P
716
+ "K": 0.287 # 28.7% K
717
  }
718
  }
719
 
720
+ class NutrientCalculator:
721
  def __init__(self, volume_liters=1.0):
722
+ self.volume = volume_liters # Объем раствора в литрах
723
+ self.results = {}
724
+
725
+ def calculate(self, profile):
726
+ """Основной расчет"""
727
+ # Сначала считаем удобрения, содержащие только один нужный элемент
728
+ self._calc_single_component(profile)
729
+ # Затем комплексные удобрения
730
+ self._calc_complex(profile)
731
+ return self.results
732
+
733
+ def _calc_single_component(self, profile):
734
+ """Расчет для простых солей"""
735
+ # Сульфат магния (Mg + S)
736
+ if 'Mg' in profile and 'S' in profile:
737
+ mg_needed = profile['Mg']
738
+ s_needed = profile['S']
739
+
740
+ # Вычисляем через Mg
741
+ mg_grams = (mg_needed * self.volume) / (fertilizers_db["Сульфат магния"]["Mg"] * 1000)
742
+ # Пересчитываем сколько S мы получим
743
+ s_from_mg = mg_grams * fertilizers_db["Сульфат магния"]["S"] * 1000 / self.volume
744
+
745
+ self.results["Сульфат магния"] = {
746
+ 'граммы': round(mg_grams, 3),
747
+ 'миллиграммы': int(mg_grams * 1000),
748
+ 'внесет S': round(s_from_mg, 1)
749
+ }
750
+ profile['S'] -= s_from_mg
751
+
752
+ def _calc_complex(self, profile):
753
+ """Расчет для комплексных удобрений"""
754
+ # Кальциевая селитра (Ca + NO3)
755
+ if 'Ca' in profile and 'N (NO3-)' in profile:
756
+ ca_grams = (profile['Ca'] * self.volume) / (fertilizers_db["Кальциевая селитра"]["Ca"] * 1000)
757
+ no3_from_ca = ca_grams * fertilizers_db["Кальциевая селитра"]["N (NO3-)"] * 1000 / self.volume
758
+
759
+ self.results["Кальциевая селитра"] = {
760
+ 'граммы': round(ca_grams, 3),
761
+ 'миллиграммы': int(ca_grams * 1000),
762
+ 'внесет NO3': round(no3_from_ca, 1)
763
+ }
764
+ profile['N (NO3-)'] -= no3_from_ca
765
+
766
+ # Монофосфат калия (P + K)
767
+ if 'P' in profile and 'K' in profile:
768
+ p_grams = (profile['P'] * self.volume) / (fertilizers_db["Монофосфат калия"]["P"] * 1000)
769
+ k_from_p = p_grams * fertilizers_db["Монофосфат калия"]["K"] * 1000 / self.volume
770
+
771
+ self.results["Монофосфат калия"] = {
772
+ 'граммы': round(p_grams, 3),
773
+ 'миллиграммы': int(p_grams * 1000),
774
+ 'внесет K': round(k_from_p, 1)
775
+ }
776
+ profile['K'] -= k_from_p
777
+
778
+ # Калий азотнокислый (K + NO3)
779
+ if 'K' in profile and profile['K'] > 0 and 'N (NO3-)' in profile:
780
+ k_grams = (profile['K'] * self.volume) / (fertilizers_db["Калий азотнокислый"]["K"] * 1000)
781
+ no3_from_k = k_grams * fertilizers_db["Калий азотнокислый"]["N (NO3-)"] * 1000 / self.volume
782
+
783
+ self.results["Калий азотнокислый"] = {
784
+ 'граммы': round(k_grams, 3),
785
+ 'миллиграммы': int(k_grams * 1000),
786
+ 'внесет NO3': round(no3_from_k, 1)
787
+ }
788
+ profile['N (NO3-)'] -= no3_from_k
789
+
790
+ # Аммоний азотнокислый (NH4 + NO3)
791
+ if 'N (NH4+)' in profile and profile['N (NH4+)'] > 0:
792
+ nh4_grams = (profile['N (NH4+)'] * self.volume) / (fertilizers_db["Аммоний азотнокислый"]["N (NH4+)"] * 1000)
793
+ no3_from_nh4 = nh4_grams * fertilizers_db["Аммоний азотнокислый"]["N (NO3-)"] * 1000 / self.volume
794
+
795
+ self.results["Аммоний азотнокислый"] = {
796
+ 'граммы': round(nh4_grams, 3),
797
+ 'миллиграммы': int(nh4_grams * 1000),
798
+ 'внесет NO3': round(no3_from_nh4, 1)
799
+ }
800
+ profile['N (NO3-)'] -= no3_from_nh4
801
+
802
+ def print_report(self, profile):
803
+ """Красивый вывод результатов"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
804
  print("\n" + "="*50)
805
+ print(f"РАСЧЕТ ДЛЯ {self.volume} ЛИТРОВ РАСТВОРА")
806
  print("="*50)
 
 
 
807
 
808
+ print("\nЦЕЛЕВОЙ ПРОФИЛЬ (ppm):")
809
+ print(tabulate([(k, v) for k, v in profile.items()],
810
+ headers=["Элемент", "Концентрация"]))
811
+
812
+ print("\nРЕКОМЕНДУЕМЫЕ УДОБРЕНИЯ:")
813
+ table = []
814
+ for fert, data in self.results.items():
815
+ table.append([
816
+ fert,
817
+ f"{data['граммы']:.3f} г",
818
+ f"{data['миллиграммы']} мг",
819
+ f"+{list(data.keys())[2]} {data[list(data.keys())[2]]} ppm"
820
+ ])
821
+ print(tabulate(table,
822
+ headers=["Удобрение", "Граммы", "Миллиграммы", "Дополнительно"]))
823
+
824
+ print("\nОСТАТОЧНЫЙ ДЕФИЦИТ:")
825
+ print(tabulate([(k, v) for k, v in profile.items() if v > 0.1],
826
+ headers=["Элемент", "Недостача (ppm)"]))
827
+
828
+ # Пример использования
829
+ calc = NutrientCalculator(volume_liters=10) # Для 10 литров раствора
830
+ results = calc.calculate(TOMATO_PROFILE.copy())
831
+ calc.print_report(TOMATO_PROFILE.copy())
832
 
833
 
834