def unstable(self, comps, is_input): for c in comps: comp = str(c) if comp in db_unstable: prod = db_unstable[comp] del comps[comps.index(c)] comps += list(map(lambda c: Compound(c), prod)) coef = self.coefs[c.formula.value] del self.coefs[c.formula.value] cs = "" for _p in prod: p = Compound(_p) self.coefs[_p] = coef cs += index(coef) + repr(p) if not is_input: if is_gase(p): cs += "↑" elif not is_ionic_soluble(p): cs += "↓" cs += " + " cs = cs[:-3:] self.bal_value = \ self.bal_value.replace(index(coef) + repr(c), cs) return comps
def iSaNo_create(kat, kat_oxs, an, an_oxs): # Kat{kat_q}An{an_q} mult = lcm(kat_oxs, an_oxs) kat_q = int(mult / kat_oxs) an_q = int(mult / an_oxs) if an_q > 1 and count_if(an, lambda c: c.isupper()) != 1 and an[0] != '[': an = "(" + an + ")" iSa = kat + index(kat_q) + an + index(an_q) return iSa
def iAc_el_create(x: str, x_oxs: int) -> (str): # H{h_q}ElO{o_q} if x == "P" and x_oxs == 5: return "H3PO4" h_q = 1 + (x_oxs + 1) % 2 o_q = int((h_q + x_oxs) / 2) iAc = "H" + index(h_q) + x + "O" + index(o_q) return iAc
def iSaAc_create(kat, kat_oxs, an, an_oxs, h_q=1): #Kat{kat_q}H{h_q}An{an_q} mult = lcm(kat_oxs, an_oxs - h_q) kat_q = int(mult / kat_oxs) an_q = int(mult / (an_oxs - h_q)) if an_q > 1: an = "(" + "H" + index(h_q) + an + ")" else: an = "H" + index(h_q) + an iSa = kat + index(kat_q) + an + index(an_q) return iSa
def iBa_create(x: str, x_oxs: int) -> (str): # El(OH){x_oxs} OH = "(OH)" if x_oxs == 1: OH = "OH" iBa = x + OH + index(x_oxs) return iBa
def iSaBa_create(kat, kat_oxs, an, an_oxs, oh_q=1): # Kat{kat_q}(OH){oh_q}An{an_q} mult = lcm(kat_oxs - oh_q, an_oxs) kat_q = int(mult / (kat_oxs - oh_q)) an_q = int(mult / an_oxs) oh = "(OH)" + index(oh_q) if kat_q > 1: kat = "(" + kat + oh + ")" else: kat = kat + oh if an_q > 1 and count_if(an, lambda c: c.isupper()) != 1: an = "(" + an + ")" iSa = kat + index(kat_q) + an + index(an_q) return iSa
def _iSaAc_oxs(salt): # MeHAn val = salt.formula.value is_dig_up_br = lambda c: c.isdigit() or c.isupper() or c == "(" me: str me_q: int me_oxs: int h_q: int anion: str an_q: int an_oxs: int me_end_pos = find_if(val[1:], is_dig_up_br) me = val[0:me_end_pos + 1] consist = deepcopy(salt.formula.consist) me_q = consist[Element(me)] del consist[Element(me)] h_q = consist[Element("H")] del consist[Element("H")] anh_beg_pos = find_if(val[1:], lambda c: c.isupper()) + 1 anh_end_pos = find_if(val[anh_beg_pos:], lambda c: c == ')') + anh_beg_pos if anh_end_pos == anh_beg_pos - 1: anh_end_pos = len(val) anionh = val[anh_beg_pos:anh_end_pos] # HAn an_beg_pos = find_if(anionh[1:], lambda c: c.isupper()) + 1 an_end_pos = find_if(anionh[an_beg_pos:], lambda c: c == ')') + an_beg_pos if an_end_pos == an_beg_pos - 1: an_end_pos = len(val) anion = anionh[an_beg_pos:an_end_pos] # An an = Compound(anion) if len(an.formula.consist) == 1: # MeNm anion = list(an.formula.consist.keys())[0].name an = Compound(anion) nonme = list(consist.keys())[0] an_q = int(consist[nonme] / an.formula.consist[nonme]) if anion in db_anions: an_oxs = db_anions[anion] me_oxs = (an_oxs * an_q - h_q) / me_q elif me in db_oxs and db_oxs[me] != [0]: me_oxs = get_me_oxs(me) an_oxs = (me_oxs * me_q + h_q) / an_q else: me_oxs = 1 an_oxs = (me_oxs * me_q + h_q / an_q) anion = "H" + index(_h_q) + anion return ((me, int(me_oxs)), (anion, int(an_oxs)))
def iSaCo_create(k_cxs: (str, int, int), an_cxs: (str, int, int)) -> (str): is_up = lambda c: c.isupper() kat = "" kat_oxs = 0 for k in k_cxs: if count_if(k[0], is_up) > 1: kat += "(" + k[0] + ")" else: kat += k[0] kat += index(k[2]) kat_oxs += k[2] * k[1] if len(k_cxs) != 1: kat = "[" + kat + "]" an = "" an_oxs = 0 for a in an_cxs: if count_if(a[0], is_up) > 1: an += "(" + a[0] + ")" else: an += a[0] an += index(a[2]) an_oxs += a[2] * a[1] if len(an_cxs) != 1: an = "[" + an + "]" if kat_oxs == 0: kat_oxs = 1 if an_oxs == 0: an_oxs = 1 an_oxs = abs(an_oxs) mult = lcm(kat_oxs, an_oxs) kat_q = int(mult / kat_oxs) an_q = int(mult / an_oxs) iCo = kat + index(kat_q) + an + index(an_q) return iCo
def oHAr_create(n: int) -> (str): res = "Bz" for i in range(min(n, 6)): res += "(-CH3)" if n < 6: res += "H" + index(6-n) sub = "(-" for i in range(6, n): sub += "CH2-" sub += "CH3)" res = res.replace("(-CH3)", sub, 1) return res
def id_iAc(): # acid if formula.value[0] != "H": return "" if formula.value == "H2O2": return "" if Element("H") not in formula.consist: return "" if Element("C") in formula.consist: if formula.value not in ["H2CO3", "HCN", "HCNO"]: return "nil" if key_in_dict(formula.consist, isMe) \ and len(formula.consist) < 3: return "" def id_iAcOx(): # acid with oxygen if Element("O") in formula.consist: return "iAcOx" def id_iAcNox(): # acid without oxygen return "iAcNox" def id_iAcCo(): # complex base if '[' in formula.value: return "iAcCo" sub_fns = [id_iAcCo, id_iAcOx, id_iAcNox] for fn in sub_fns: comp_type = fn() if comp_type: val = formula.value pos = 0 while val[pos] == 'H': pos += 1 val = "H" + index(pos) + val[pos:] comp.formula = Formula(val) return comp_type return ""
def balance(self): comps = self.inp + self.outp elems = [] for comp in comps: for el in comp.formula.consist: if el.name == "Amm": elems.append(Element("N")) elems.append(Element("H")) else: elems.append(el) bz = False if Element("Bz") in elems: del elems[elems.index(Element("Bz"))] elems.append(Element("C")) bz = True elems = list(set(elems)) rows = [] for i in elems: rows.append([]) for comp in self.inp: for i in range(len(elems)): val = 0 if Element("Amm") in comp.formula.consist: if elems[i].name == "H": val += comp.formula.consist[Element("Amm")] * 4 elif elems[i].name == "N": val += comp.formula.consist[Element("Amm")] if Element("Bz") in comp.formula.consist: if elems[i].name == "C": val += comp.formula.consist[Element("Bz")] * 6 if elems[i] in comp.formula.consist: val += comp.formula.consist[elems[i]] rows[i].append(val) for comp in self.outp: for i in range(len(elems)): val = 0 if Element("Amm") in comp.formula.consist: if elems[i].name == "H": val += comp.formula.consist[Element("Amm")] * 4 elif elems[i].name == "N": val += comp.formula.consist[Element("Amm")] if Element("Bz") in comp.formula.consist: if elems[i].name == "C": val += comp.formula.consist[Element("Bz")] * 6 if elems[i] in comp.formula.consist: val += comp.formula.consist[elems[i]] rows[i].append(-val) while len(rows[0]) > len(rows): rows.append([0] * len(comps)) free = [r.pop(-1) for r in rows] while len(rows) > len(rows[0]): for i in range(len(rows)): rows[i].append(0) (coefs, _, _, _) = np.linalg.lstsq(np.array(rows), np.array(free), rcond=None) coefs = coefs.tolist() coefs = [abs(c) for c in coefs if c != 0] m = min(coefs) coefs = list(map(lambda c: round(rnd((c / m) * 2520)), coefs)) coefs.append(round(rnd((1 / m) * 2520))) div = coefs[0] for c in coefs: div = gcd(c, div) coefs = list(map(lambda c: int(round(c) / div), coefs)) val = "" for i in range(len(self.inp)): val += index(coefs[i]) val += repr(self.inp[i]) val += " + " val = val[0:-2] val += "→ " for i in range(len(self.outp)): val += index(coefs[len(self.inp) + i]) val += repr(self.outp[i]) if is_gase(self.outp[i]): val += "↑" elif not is_ionic_soluble(self.outp[i]): val += "↓" val += " + " val = val[0:-2] self.coefs = dict(zip(map(lambda c: c.formula.value, comps), coefs)) return val
def iOx_create(x: str, x_oxs: int) -> (str): # El{x_q}O{o_q} x_q = 1 + x_oxs % 2 o_q = int(x_q * x_oxs / 2) iOx = x + index(x_q) + "O" + index(o_q) return iOx
def iAc_create(an: str, an_oxs: int) -> (str): # H{an_oxs}An iAc = "H" + index(an_oxs) + an return iAc