def sort(self, for_variable): """Sorts a Standard Form linear equation to be solved for a given variable. Keyword arguments: variable (str): the variable this equation will be sorted to solve for.""" # Required and convenient variables definition. eqtn = self.equation c_pos, a, b = eqtn.find( "=") + 1, self.x_coefficient, self.y_coefficient c = self.get_number(c_pos, eqtn) den = if_assign(for_variable == 'y', a, b) mult = if_assign(for_variable == 'y', b, a) if eqtn[eqtn.index(for_variable) - len(str(mult)) - 1] == "-": operator = "+" else: operator = "-" # Expressing sol_side = "(" + c + operator + mult + "*" + for_variable + ")" + "/" + den sol_side = Expression.beautify(sol_side) return sol_side
def substract(a, b): """Returns the expression resultant of substracting terms a and b.""" a = Expression(a, no_vars_intended=True) b = Expression(b, no_vars_intended=True) if isanumber(a.expression) or isanumber(b.expression): raise NonAlgebraicOperationError if len(a.terms) > 1 or len(b.terms) > 1: raise InvalidOperationError(a, b) if TermOperations.getpower( a.expression) is not TermOperations.getpower( b.expression) or a.variables != b.variables: result = a.expression + '-' + b.expression return Expression.beautify(result) a_coefficient = a.get_number(0, frac_to_number=True) b_coefficient = b.get_number(0, frac_to_number=True) result = str(num(a_coefficient) - num(b_coefficient)) result = if_assign(result == '1', "", result) result = if_assign(result == '-1', "-", result) result += "".join(a.variables) + '**' + str( TermOperations.getpower(a.expression)) return Expression.beautify(result)
def add(a, b, non_algebraic=False): """Returns the expression resultant of adding terms a and b.""" a = Expression(a, no_vars_intended=True) b = Expression(b, no_vars_intended=True) if isanumber(a.expression) or isanumber(b.expression): if non_algebraic is True: return num(num(a.expression) + num(b.expression)) raise NonAlgebraicOperationError if len(a.terms) > 1 or len(b.terms) > 1: raise InvalidOperationError(a, b) if TermOperations.getpower( a.expression) is not TermOperations.getpower( b.expression) or a.variables != b.variables: operator = if_assign(b.expression.startswith('-'), '', '+') return Expression.beautify(a.expression + operator + b.expression) a_coefficient = a.get_number(0) b_coefficient = b.get_number(0) result = str(num(a_coefficient) + num(b_coefficient)) result = if_assign(result == '1', "", result) result = if_assign(result == '-1', "-", result) result += "".join(a.variables) + '**' + str( TermOperations.getpower(a.expression)) if result.endswith('**1'): result = result.replace('**1', '') return Expression.beautify(result)
def multiply(a, b): """Multiplies terms a and b.""" a = Expression(a, no_vars_intended=True) b = Expression(b, no_vars_intended=True) power = str( if_assign( TermOperations.getpower(a.expression) >= TermOperations.getpower(b.expression), TermOperations.getpower(a.expression), TermOperations.getpower(b.expression))) variables = set(a.variables + b.variables) if len(TermOperations.commonvars(a.expression, b.expression)) > 0: power = str( int(TermOperations.getpower(a.expression)) + int(TermOperations.getpower(b.expression))) power = if_assign(power == '1', '', power) if power == '1': return "".join(variables) a_coefficient = a.get_number(0) b_coefficient = b.get_number(0) result = str(int(a_coefficient) * int(b_coefficient)) + "".join(variables) + '**' + power return Expression.beautify(result)
def get_coefficients(self): """Returns every coefficient on this expression.""" coefficients = [] for term in self.terms: if any(char.isalpha() for char in term): coefficient = self.get_number(0, term) coefficient = if_assign(coefficient is '', '1', coefficient) coefficient = if_assign(coefficient is '-', '-1', coefficient) coefficients.append(coefficient) return coefficients
def sort_for_y(self): """Sorts equation for y.""" eqtn, sol_side = self.equation, self.rhs x_index = eqtn.index('x') operator = if_assign(eqtn[x_index + 1] == '-', '+', '-') slope_sign = if_assign(eqtn[0] == '-', '-', '') sol_side = "(" + self.y_coefficient + "*y" + operator + \ str(self.y_intercept).replace('-', '') + ")/" + slope_sign + str(self.slope) sol_side = Expression.beautify(sol_side) return sol_side
def get_x_coefficient(self): """Returns whatever number is multiplying the x variable on this equation as a string.""" side = if_assign(self.form is LinearForms.Standard, self.equation, self.rhs) if side[0] == '-': coefficient = if_assign(side[1].isdigit(), self.get_number(1, side), "1") return '-' + coefficient if side[0].isdigit(): coefficient = self.get_number(0, side) else: coefficient = 1 return coefficient
def legal_moves(self): advancements = if_assign( self.has_moved, 1, 2) # Can the pawn advance two squares or just one? rank = int(self.get_pos().rank) next_rank = str(rank + 1) file_index = FILES.index(self.get_pos().file) # Find the squares in front of the pawn and check if they have any piece. # If they don't, add them to the legal moves of this pawn. legal_moves = self.board.get_file(self.get_pos().file)[rank:rank + advancements] legal_moves = list(filter(lambda x: x.piece is None, legal_moves)) # Find the squares diagonally adjacent to the pawn. If they have an enemy piece, # add them to the legal moves. diagonal_coords = [ FILES[file_index + 1] + next_rank, FILES[file_index - 1] + next_rank ] capture_squares = [ self.board.get_square(diagonal_coords[0]), self.board.get_square(diagonal_coords[1]) ] for sq in capture_squares: if sq.has_piece() and sq.piece.color is self.get_opposite_color(): legal_moves.append(sq) return legal_moves
def divide(a, b): a = Expression(a) b = Expression(b) variables = set(a.variables + b.variables) power = '**' + str( int(TermOperations.getpower(a.expression)) - int(TermOperations.getpower(b.expression))) power = if_assign(power == '**1', '', power) if power == '**0': return "/".join(variables) a_coefficient = a.get_number(0) b_coefficient = b.get_number(0) result = str(num( int(a_coefficient) / int(b_coefficient))) + "/".join(variables) result = if_assign(power != '', '(' + result + ')' + power, result) return Expression.beautify(result)
def get_y_coefficient(self): """Returns whatever number is multiplying the y variable on this equation""" eqtn, index = self.equation, self.equation.index('x') + 2 if self.form == LinearForms.Standard: coefficient = if_assign(eqtn[index].isdigit(), self.get_number(index, eqtn), "1") if eqtn[index - 1] == '-': coefficient = '-' + coefficient else: if eqtn[0] == '-': coefficient = if_assign(eqtn[1].isdigit(), self.get_number(1, eqtn), "1") coefficient = '-' + coefficient else: coefficient = if_assign(eqtn[0].isdigit(), self.get_number(0, eqtn), "1") return coefficient
def express_as(self, form): """Expresses the equation in the form passed as an argument and returns an instance of that form's class as the new expression. Valid forms are , Standard and . Keyword arguments: form (str): the form the equation will be converted to""" eqtn, slope = self.equation, str(self.slope) if not isinstance(form, LinearForms): raise InvalidFormError(form) if form is self.form: raise RedundantConversionError(self.form, form) if form is LinearForms.SlopeIntercept: operator = if_assign(self.y_intercept < 0, '', '+') rewritten = 'y=' + slope + "x" + operator + str(self.y_intercept) if '--' in rewritten: rewritten = rewritten.replace('--', '+') return SlopeIntercept(rewritten) if form is LinearForms.Standard: operator = if_assign(eqtn[0] == '-', '-', '+') y_coefficient = if_assign(self.y_coefficient == '1', '', self.y_coefficient) rewritten = '-' + self.x_coefficient + 'x' + operator + \ y_coefficient + 'y' + '=' + str(self.y_intercept) rewritten = Expression.beautify(rewritten) return Standard(rewritten) raise InvalidFormError(form)
def sort_for_x(self): """Sorts equation for x.""" eqtn, sol_side, y_coefficient = self.equation, self.rhs, self.y_coefficient x_index = eqtn.index('x') # Set the solution side sol_side = "(" + sol_side + ")/" + y_coefficient # Add a * symbol before the x if there's a number before it. sol_side = if_assign(eqtn[x_index - 1].isdigit(), sol_side.replace('x', '*x'), sol_side) # Beautify the solution side. sol_side = Expression.beautify(sol_side) return sol_side
def sort_for_y(self): """Sorts equation for y.""" # Required and convenient variables definition. eqtn, y_index = self.equation, self.equation.index('y') x_index = eqtn.index('x') y_point = self.get_number(y_index + 2, eqtn) x_point = self.get_number(x_index + 2, eqtn) x_point_op = if_assign(eqtn[x_index + 1] == '-', '-', '+') # Expression sol_side = "(y" + eqtn[y_index + 1] + y_point + "-" + str(self.slope) + \ "*" + x_point_op + x_point + ")/" + str(self.slope) sol_side = Expression.beautify(sol_side) return sol_side
def express_as(self, form): """Expresses the equation in the form passed as an argument and returns an instance of that form's class as the new expression. Valid forms are , Standard and . Keyword arguments: form (str): the form the equation will be converted to""" # Required and convenient variables definition. slope, y_intercept = str(self.slope), str(self.y_intercept) if not isinstance(form, LinearForms): raise InvalidFormError(self.equation.form, form) if form == self.form: raise RedundantConversionError(self.form, form) # Express in Standard Form. if form is LinearForms.Standard: slope = slope.replace('-', '') x_op = if_assign(self.slope < 0, '', '-') # 'y' will always be positive, for negative multipliers of it will # be distributed. Hence why '+' is the operator before 'y'. rewritten = x_op + slope + "x" + '+' + "y" + "=" + y_intercept rewritten = Expression.beautify(rewritten) return Standard(rewritten) # Express in form. if form is LinearForms.PointSlope: points = self.get_point(2) x_point, y_point = str(points[0]), str(points[1]) rewritten = "y-" + y_point + "=" + slope + "(x-" + x_point + ")" rewritten = Expression.beautify(rewritten) return PointSlope(rewritten) raise InvalidFormError(form)
def solve(self, debug=False): """Returns the solution of the equation as integer or float, depending on what the solution is.""" rhs_no_var_terms = [ num(term) for term in Expression( self.rhs, no_vars_intended=True).get_terms() if isanumber(term) ] lhs_no_var_terms = [ num(term) for term in Expression( self.lhs, no_vars_intended=True).get_terms() if isanumber(term) ] rhs_var_terms = [ term for term in Expression(self.rhs, no_vars_intended=True).get_terms() if any(var in term for var in self.variables) ] lhs_var_terms = [ term for term in Expression(self.lhs, no_vars_intended=True).get_terms() if any(var in term for var in self.variables) ] polynomial = '+'.join(lhs_var_terms) + '-' + '+'.join(rhs_var_terms) polynomial = if_assign(polynomial.endswith('-'), polynomial[:-1], polynomial) lhs = Polynomial(polynomial) coefficient = self.get_number(0, lhs.polynomial) result = sum(rhs_no_var_terms) - sum(lhs_no_var_terms) if debug: print(lhs, '=', result, '-->', str(result) + '/(' + coefficient + ')') if coefficient is '0': if result == 0: return "All real numbers are solutions." return "No solutions." return num(str((eval(str(result) + '/(' + coefficient + ')'))))
def sort_for_x(self): """Sorts equation for x.""" eqtn, y_index = self.equation, self.equation.index('y') x_index = eqtn.index('x') y_point = self.get_number(y_index + 2, eqtn) x_point = self.get_number(x_index + 2, eqtn) slope_pos = self.equal_index + 1 # Gets the slope instead of using self.slope because this method is called # before defining (and to define) the slope attribute. slope = self.get_number(slope_pos, eqtn) first_op = if_assign(eqtn[y_index + 1] == '-', '+', '-') second_op = eqtn[x_index + 1] sol_side = slope + "*(x" + second_op + x_point + ")" + first_op + y_point sol_side = Expression.beautify(sol_side) return sol_side
def get_opposite_color(self): opposite = if_assign(self.color is Colors.WHITE, Colors.BLACK, Colors.WHITE) return opposite