def __add__(self, left): if is_digit(self.contain) and is_digit(left.contain): if left.coef == 1: self.contain += left.contain else: self.contain -= left.contain elif self.contain == left.contain: if self.expo == left.expo: self.coef += left.coef if self.coef == 0: self.coef = 1 self.contain = 0 self.expo = 1 else: dic = { (self.sign, self.contain, self.expo): self, (left.sign, left.contain, left.expo): left } self.coef = 1 self.contain = deepcopy(dic) self.expo = 1 else: dic = { (self.sign, self.contain, self.expo): self, (left.sign, left.contain, left.expo): left } self.coef = 1 self.contain = deepcopy(dic) self.expo = 1 return self
def get_range(self): if is_digit(self.x_value1.text()) and is_digit(self.x_value2.text()): self.ran_x[0] = float(self.x_value1.text()) self.ran_x[1] = float(self.x_value2.text()) self.interval_x = (self.ran_x[1] - self.ran_x[0]) / self.n_interval else: self.tt_label.setText(' Write ONLY digits') return 0 if len(self.var_list) == 2: if is_digit(self.y_value1.text()) and is_digit( self.y_value2.text()): self.ran_y[0] = float(self.y_value1.text()) self.ran_y[1] = float(self.y_value2.text()) self.interval_y = (self.ran_y[1] - self.ran_y[0]) / self.n_interval else: self.tt_label.setText(' Write ONLY digits') return 0 if self.ran_x[0] >= self.ran_x[1] or self.ran_y[0] >= self.ran_y[1]: self.tt_label.setText( ' The Right value must be bigger than the Left value') return 0 self.plot()
def calc(self, left): factor = self.factor.eval() if self.op == '^': if is_digit(left.contain) and is_digit(factor.contain): left.contain = left.contain**factor.contain else: left.expo = factor * left.expo # left.expo *= factor # left = left ** factor if self.sequenceTail is None: return left else: return self.sequenceTail.calc(left)
def plot_2D(eq, domain, in_domain, var_list, ran, interval): var = var_list[0] ipts = [] opts = [] ipt = [] opt = [] for n in range(int((ran[1]-ran[0])/interval)): value = ran[0] + interval * n if check_domain(domain, in_domain, var_list, var+'='+str(value)): ans = change_x_to_num(eq, var_list, var + '=' + str(value)) if is_digit(ans): ipt.append(value) opt.append(float(ans)) else: ipts.append(ipt) opts.append(opt) ipt = [] opt = [] else: ipts.append(ipt) opts.append(opt) ipt = [] opt = [] ipts.append(ipt) opts.append(opt) return [ipts, opts]
def plot_3D(eq, domain, in_domain, var_list, ran1, ran2, interval_x, interval_y): var1 = var_list[0] var2 = var_list[1] ipt1 = [] ipt2 = [] opt = [] for n in range(int((ran1[1]-ran1[0])/interval_x)): value1 = ran1[0] + interval_x * n for m in range(int((ran2[1]-ran2[0])/interval_y)): value2 = ran2[0] + interval_y * m if check_domain(domain, in_domain, var_list, var1+'='+str(value1) +','+ var2+'='+str(value2)): ans = change_x_to_num(eq, var_list, var1+'='+str(value1) +','+ var2+'='+str(value2)) ipt1.append(value1) ipt2.append(value2) if is_digit(ans): opt.append(float(ans)) else: opt.append(nan) else: ipt1.append(value1) ipt2.append(value2) opt.append(nan) return [ipt1, ipt2, opt]
def check_domain(domain, in_domain, var_list, input): if domain: domain = domain_to_string(domain, var_list) if in_domain: in_domain = domain_to_string(in_domain, var_list) for n in range(len(domain)): opt = change_x_to_num(domain[n], var_list, input) if is_digit(opt): if float(opt) == 0: return 0 else: return 0 for n in range(len(in_domain)): opt = change_x_to_num(in_domain[n], var_list, input) if is_digit(opt): if float(opt) < 0: return 0 else: return 0 return 1
def differentiable_1D(eq, eq_diff, domain, in_domain, string, var_list): try: epsilon = 10 ** -10 var = [] value = [] string1 = string.replace(" ", "") string1 = string1.split(',') for n in range(len(string1)): temp = string1[n].split('=') if temp[0] not in var_list: raise Exception('%s is not in current variable list' % (temp[0])) if len(temp) != 2 or not is_digit(temp[1]): raise Exception('Wrong input') var.append(temp[0]) value.append(temp[1]) if len(var) != 1: raise Exception('Expected 1 variable but got %d' % (len(var))) else: var = var[0] value = value[0] if check_domain(domain, in_domain, [var], var+'='+str(float(value)+epsilon)): ans_l_p = change_x_to_num(eq, [var], var+'='+str(float(value)+epsilon)) ans_d_l_p = change_x_to_num(eq_diff[0], [var], var+'='+str(float(value)+epsilon)) else: return 0 if check_domain(domain, in_domain, [var], var+'='+str(float(value)-epsilon)): ans_l_m = change_x_to_num(eq, [var], var+'='+str(float(value)-epsilon)) ans_d_l_m = change_x_to_num(eq_diff[0], [var], var+'='+str(float(value)-epsilon)) else: return 0 if check_domain(domain, in_domain, [var], var+'='+str(value)): ans = change_x_to_num(eq, [var], var+'='+value) ans_d = change_x_to_num(eq_diff[0], [var], var+'='+value) else: return 0 if is_same([ans_l_p, ans_l_m, ans], epsilon) and is_same([ans_d_l_p, ans_d_l_m, ans_d], epsilon): return 1 else: return 0 except Exception as e: return '*Error* ' + str(e)
def change_x_to_num(eq, var_list, string): try: eq = eq.replace(" ", "") eq_list = tokenize(eq, var_list) variable = [] value = [] string = string.replace(" ", "") string = string.split(',') for n in range(len(string)): temp = string[n].split('=') if temp[0] not in var_list: raise Exception('%s is not in current variable list' % (temp[0])) if len(temp) != 2 or not is_digit(temp[1]): raise Exception('Wrong input') variable.append(temp[0]) value.append(temp[1]) for n in range(len(variable)): eq_temp = [] for m in range(len(eq_list)): if eq_list[m] == variable[n]: eq_temp.append(float(value[n])) else: eq_temp.append(eq_list[m]) eq_list = eq_temp if eq_list[0] == 'sig': sig_eq = '' for n in range(4, len(eq_list)-6): sig_eq += str(eq_list[n]) ans, _, _ = sigma(eq_list[2], sig_eq, eq_list[-5], eq_list[-3], var_list) return ans[0] E = Parser(eq_list, var_list) ans = E.eval() return from_list_to_str('', ans) except Exception as e: return '*Error* ' + str(e)
def calc(self, left): factor = self.factor.eval() if self.op == '^': if factor == [2]: left = many_mul([], left, left, var_list) else: if is_digit(factor[0]) and len(factor) == 1: if 0 < factor[0] < 1: if left not in in_eq: in_eq.append(left) left = power(left, factor, var_list) left = double_bracket(left) if self.sequenceTail is None: return left else: return self.sequenceTail.calc(left)
def eval(self): if isinstance(self.expr, Expr): a = self.expr.eval() self.contain = a else: self.contain = self.expr if self.sign is '-': self.coef *= -1 return self elif self.sign in self.funcs_list: func = self.funcs[self.sign] if is_digit(self.contain): self.contain = func(self.contain) self.sign = None # elif self.sign == 'log': # elif self.sign == 'sig': return self
def __mul__(self, left): if is_digit(left): self.contain *= left elif is_digit(self.contain) and is_digit(left.contain): expo = left.expo if is_digit(left.expo) else left.expo.contain if expo == 1: self.contain *= left.contain else: self.contain /= left.contain elif is_digit(self.contain): if self.expo == 1: left.coef *= (self.coef * self.contain) else: left.coef /= (self.coef * self.contain) return left elif is_digit(left.contain): if left.expo == 1: self.coef *= (left.coef * left.contain) else: self.coef /= (left.coef * left.contain) else: if self.contain == left.contain: self.coef *= left.coef self.expo += left.expo if self.expo == 0: if self.coef > 0: self.contain = self.coef self.coef = 1 else: self.contain = self.coef * -1 self.coef = -1 self.expo = 1 return self
def differentiable_2D(eq, eq_diff, domain, in_domain, string, var_list): try: epsilon = 10**(-10) var = [] value = [] string1 = string.replace(" ", "") string1 = string1.split(',') for n in range(len(string1)): temp = string1[n].split('=') if temp[0] not in var_list: raise Exception('%s is not in current variable list' % (temp[0])) if len(temp) != 2 or not is_digit(temp[1]): raise Exception('Wrong input') var.append(temp[0]) value.append(temp[1]) if len(var) != 2: raise Exception('Expected 2 variable but got %d' % (len(var))) PlusMinus_epsilon = [+epsilon, -epsilon] ans_l_x = [] ans_l_dx = [] ans_l_y = [] ans_l_dy = [] for n in range(len(PlusMinus_epsilon)): temp_string = var[0] + '=' + str(float(value[0])+PlusMinus_epsilon[n]) + ',' + var[1] + '=' + value[1] if check_domain(domain, in_domain, var, temp_string): ans_l_x.append(change_x_to_num(eq, var, temp_string)) ans_l_dx.append(change_x_to_num(eq_diff[0], var, temp_string)) else: return [0, 0] for n in range(len(PlusMinus_epsilon)): temp_string = var[0] + '=' + value[0] + ',' + var[1] + '=' + str(float(value[1])+PlusMinus_epsilon[n]) if check_domain(domain, in_domain, var, temp_string): ans_l_y.append(change_x_to_num(eq, var, temp_string)) ans_l_dy.append(change_x_to_num(eq_diff[0], var, temp_string)) else: return [0, 0] if check_domain(domain, in_domain, var, string): ans = change_x_to_num(eq, var, string) ans_dx = change_x_to_num(eq_diff[0], var, string) ans_dy = change_x_to_num(eq_diff[1], var, string) else: return [0, 0] epsilon = epsilon * 10 if is_same([ans_l_x[0], ans_l_x[1], ans], epsilon): if is_same([ans_l_dx[0], ans_l_dx[1], ans_dx], epsilon): dx = 1 else: return [0, 0] else: return [0, 0] if is_same([ans_l_y[0], ans_l_y[1], ans], epsilon): if is_same([ans_l_dy[0], ans_l_dy[1], ans_dy], epsilon): dy = 1 else: return [0, 0] else: return [0, 0] return [dx, dy] except Exception as e: return '*Error* ', str(e)
def on_click_eq(self): temp = self.variable.text() self.eq = self.equation.text() self.domain_title_label.setText('') self.domain_label.setText('') self.dt_label.setText('') if not self.eq: self.a_label.setText('Enter Equation') self.d_label.setText('') self.da_label.setText('') return 0 self.var_list = [] temp = temp.replace(" ", "") temp = temp.split(',') if temp[0] != '': for n in range(len(temp)): if temp[n] in ['e', 'pi']: self.a_label.setText(temp[n] + ' is not available') return 0 self.var_list.append(temp[n]) self.var_list.sort() ans, self.domain, self.in_domain = calcul(self.eq, self.var_list) if ans == 'Error': self.a_label.setText('*Error* ' + self.domain.args[0]) self.d_label.setText('') return 0 if self.eq[0:3] == 'sig': self.eq = ans[0] self.diff = [] for n in range(len(self.var_list)): differential = ans[1] if differential[0] == 'Error': self.diff = 'Error' + differential[1].args[0] break else: self.diff.append(differential[0]) else: self.eq = from_list_to_str('', ans) self.diff = [] for n in range(len(self.var_list)): differential = diff(ans, self.var_list[n], self.var_list) if differential[0] == 'Error': self.diff = 'Error' + differential[1].args[0] break else: self.diff.append(from_list_to_str('', differential[0])) self.a_label.setText('Equation is: ' + str(self.eq)) self.d_label.setText('Differential') if not self.domain and not self.in_domain: str_domain = 'Domain: R' if len(self.var_list) > 1: str_domain = str_domain + '^' + str(len(self.var_list)) self.domain_title_label.setText(str_domain) else: str_domain = '' for n in range(len(self.domain)): str_domain = str_domain + from_list_to_str( '', self.domain[n]) + ' ≠ 0' + '\n' for n in range(len(self.in_domain)): str_domain = str_domain + from_list_to_str( '', self.in_domain[n]) + ' ≥ 0' + '\n' self.domain_title_label.setText('Domain') self.domain_label.setText(str_domain) if not is_digit(self.eq): if len(self.var_list) < 3 and self.eq[0:3] != 'sig': self.open_new_dialog(self.eq, self.diff, self.domain, self.in_domain, self.var_list) if not self.diff: self.a_label.setText('Answer is: ' + str(self.eq)) self.d_label.setText('') self.da_label.setText('') return 0 diff_ans = '' if isinstance(self.diff, str): diff_ans = self.diff else: for n in range(len(self.diff)): diff_ans = diff_ans + 'Differentiated by ' + self.var_list[ n] + ': ' + self.diff[n] + '\n' self.da_label.setText(diff_ans) return 0
def eval(self): temp = self.expr.eval() if isinstance(self.expr, Expr) else self.expr if temp in var_list: temp = [1, temp, 1] elif is_digit(temp): temp = [temp] elif temp in ['e', 'pi']: temp = [self.funcs[temp]] elif is_gathered(temp) and len(temp) == 1: temp = temp[0] if self.sign is '-': temp = many_mul([], [-1], temp, var_list) return temp elif self.sign in self.funcs_list: func = self.funcs[self.sign] if not is_digit(temp[0]) or len(temp) > 1 and self.sign == 'tan': if temp not in eq: temp_pi = plus(deepcopy(temp), [pi / 2], var_list) if temp_pi not in eq: eq.append(temp_pi) if is_digit(temp[0]) and len(temp) == 1: if self.sign == 'tan' and temp[0] == (pi / 2): raise Exception('Cannot define tan(pi/2)') else: return [func(temp[0])] else: return [1, [self.sign, temp], 1] elif self.sign == 'log': if not is_digit(temp[0]) or len(temp) > 1: if temp not in in_eq: in_eq.append(temp) if temp not in eq: eq.append(temp) if self.base == None: base = [e] else: base = self.base.eval() if isinstance(self.base, Expr) else self.base if not is_digit(base[0]) or len(base) > 1: if base not in in_eq: in_eq.append(base) if base not in eq: eq.append(base) base_1 = plus(deepcopy(base), [-1], var_list) if base_1 not in eq: if not is_digit(base[0]) or len(base) > 1: eq.append(base_1) if is_digit(temp[0]) and len(temp) == 1 and is_digit( base[0]) and len(base) == 1: return [log(temp[0], base[0])] else: if not is_gathered(temp) and len(temp) == 3: if is_digit(base[0]) and len(base) == 1: if [temp[0], temp[1], 1] == [1, base, 1]: return many_mul([], [1], [temp[2]], var_list) else: return [1, ['log', temp, base], 1] # return many_mul([], [1, ['log', [temp[0], temp[1], 1], base], 1], [temp[2]], var_list) else: if [temp[0], temp[1], 1] == base: return many_mul([], [1], [temp[2]], var_list) else: return [1, ['log', temp, base], 1] # return many_mul([], [1, ['log', [temp[0], temp[1], 1], base], 1], [temp[2]], var_list) else: return [1, ['log', temp, base], 1] elif self.sign == 'sig': var_list.append(self.k) temp = self.expr.eval() if isinstance(self.expr, Expr) else self.expr var_list.pop() # sigma(self.k, temp, self.base[0], self.base[1], var_list) return [0, 'sig'] return temp
def tokenize(eq, var_list): eq_list = [] funcs_list = ['log', 'sin', 'cos', 'tan', 'pow', 'sig'] op_list = ['+', '-', '*', '/', '^', '(', ')', ','] temp = '0' for n in range(len(eq)): if n == len(eq) - 1: if is_digit(eq[n]) or eq[n] == '.': temp += str(eq[n]) eq_list.append(float(temp)) elif eq[n] in var_list: if temp != '0': eq_list.append(float(temp)) eq_list.append(eq[n]) elif eq[n - 1:n + 1] == 'pi': eq_list.pop() eq_list.append(eq[n - 1:n + 1]) elif eq[n] in op_list: if temp != '0': eq_list.append(float(temp)) eq_list.append(eq[n]) else: eq_list.append(eq[n]) elif n == 0: if is_digit(eq[n]) or eq[n] == '.': temp += str(eq[n]) if n == len(eq) - 1: eq_list.append(float(temp)) elif eq[n] in var_list or eq[n] in op_list: eq_list.append(eq[n]) else: eq_list.append(eq[n]) elif n == (1 or 2): if is_digit(eq[n]) or eq[n] == '.': temp += str(eq[n]) elif eq[n - 1:n + 1] == 'pi': eq_list.pop() eq_list.append(eq[n - 1:n + 1]) elif eq[n] in var_list or eq[n] in op_list: if is_digit(eq[n - 1]) or eq[n - 1] == '.': eq_list.append(float(temp)) temp = '0' eq_list.append(eq[n]) else: eq_list.append(eq[n]) else: if is_digit(eq[n]) or eq[n] == '.': temp += str(eq[n]) elif eq[n - 1:n + 1] == 'pi': eq_list.pop() eq_list.append(eq[n - 1:n + 1]) elif eq[n - 2:n + 1] in funcs_list: eq_list.pop() eq_list.pop() eq_list.append(eq[n - 2:n + 1]) elif eq[n] in var_list or eq[n] in op_list: if is_digit(eq[n - 1]) or eq[n - 1] == '.': eq_list.append(float(temp)) temp = '0' eq_list.append(eq[n]) else: eq_list.append(eq[n]) eq_list.append('$') return eq_list