Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python3
- '''this programm compare 2 polynoms'''
- import sys
- import re
- import argparse
- import my_exceptions
- def sort_by_alphabet(string):
- '''sorts string by alphabet'''
- lst = list(string)
- lst.sort(key=lambda x: x[0])
- return ''.join(lst)
- def add(first_polynom, second_polynom):
- '''adds 2 monomial defined in dictionary format'''
- for x in second_polynom:
- if x in first_polynom:
- first_polynom[x] += second_polynom[x]
- else:
- first_polynom[x] = second_polynom[x]
- return first_polynom
- def multiplication(first_polynom, second_polynom):
- '''multiplies 2 monomial defined in dictionary format'''
- current_poly = {}
- for x in first_polynom:
- for y in second_polynom:
- key = sort_by_alphabet(x+y)
- value = float(first_polynom[x]) * float(second_polynom[y])
- if key in current_poly:
- current_poly[key] += value
- else:
- current_poly[key] = value
- return current_poly
- def degree(first_polynom, second_polynom):
- '''elevates the degre using multiplication'''
- f = {}
- for i in first_polynom:
- if first_polynom[i] == 0.0:
- if '' not in f:
- f[''] = 0.0
- else:
- f[i] = first_polynom[i]
- first_polynom = f
- f2 = {}
- for i in second_polynom:
- if second_polynom[i] == 0.0:
- if '' not in f2:
- f2[''] = 0.0
- else:
- f2[i] = second_polynom[i]
- second_polynom = f2
- if '' not in second_polynom or len(second_polynom) > 1:
- raise my_exceptions.IncorrectSymbol("incorrect degree")
- deg = second_polynom['']
- # print(deg)
- # if len(first_polynom) == 1:
- # for i in first_polynom:
- # if first_polynom[i] == 0.0:
- # if deg == 0.0:
- # raise my_exceptions.Incorre
- if '' in first_polynom and len(first_polynom) == 1 and deg <= 0:
- if deg == 0:
- if first_polynom[''] == 0.0:
- raise my_exceptions.IncorrectSymbol("неопределенная степень")
- return {'': 1}
- if first_polynom[''] == 0:
- raise my_exceptions.IncorrectSymbol("ноль в отрицательную степень")
- return {'': 1/degree(first_polynom, {'': -deg})['']}
- if float(deg) != int(deg) or int(deg) < 0:
- raise my_exceptions.IncorrectSymbol("nonintegral degree")
- deg = int(deg)
- current_poly = multiplication(first_polynom, {'': 1})
- for _ in range(deg - 1):
- current_poly = multiplication(current_poly, first_polynom)
- if deg == 0:
- current_poly = {'': 1}
- return current_poly
- def division(first_polynom, second_polynom):
- '''check correct division'''
- new_polynom = {}
- if (len(second_polynom) > 1):
- raise my_exceptions.IncorrectSymbol("incorrect division")
- for i in second_polynom:
- for j in first_polynom:
- if i != '' and i not in list(j):
- raise my_exceptions.IncorrectSymbol("variable in divisor")
- else:
- value = first_polynom[j]
- j = j.replace(i, '')
- new_polynom[j] = value
- second_polynom = { '' : second_polynom[i] }
- first_polynom = new_polynom
- if float(second_polynom['']) == 0.0:
- raise my_exceptions.IncorrectSymbol("деление на ноль")
- divisor = second_polynom['']
- for dividend in first_polynom:
- first_polynom[dividend] = first_polynom[dividend] / float(divisor)
- return first_polynom
- def new_polynom(string, i, stack_with_polynoms, numbers, characters):
- '''creates polynom from list of characters and list of monomial'''
- value = 1
- key = ''
- while i < len(string) and string[i] not in characters:
- if re.match(numbers, string[i]):
- value *= float(string[i])
- else:
- key += string[i]
- i += 1
- #if value == 0:
- # value = 1
- stack_with_polynoms.append({sort_by_alphabet(key): value})
- return i - 1
- def math_func(stack_with_characters, stack_with_polynoms):
- '''select math function'''
- character = stack_with_characters.pop()
- second_operand = stack_with_polynoms.pop()
- if character == '`':
- stack_with_polynoms.append(multiplication(second_operand, {'': -1}))
- return
- first_operand = stack_with_polynoms.pop()
- if character == '-':
- stack_with_polynoms.append(add(first_operand, multiplication(second_operand, {'': -1})))
- elif character == '+':
- stack_with_polynoms.append(add(first_operand, second_operand))
- elif character == '*':
- stack_with_polynoms.append(multiplication(first_operand, second_operand))
- elif character == '^':
- stack_with_polynoms.append(degree(first_operand, second_operand))
- elif character == '/':
- stack_with_polynoms.append(division(first_operand, second_operand))
- def canonical_form(string):
- '''main function which makes dict from list'''
- characters = {'`': 5, '(': 0, ')': 1, '+': 2, '-': 2, '*': 3, '/': 3, '^': 4}
- correct_symbols = r'[+*\-/()\w^.]'
- numbers = r'[\d.]'
- length = len(string)
- stack_with_polynoms = []
- stack_with_characters = []
- last_is_character = True
- last_is_bracket = False
- i = 0
- while i < length:
- if not re.match(correct_symbols, string[i]):
- raise my_exceptions.IncorrectSymbol("you wrote incorrect symbol")
- if string[i] not in characters:
- i = new_polynom(string, i, stack_with_polynoms, numbers, characters)
- last_is_character = False
- else:
- if last_is_character or i == 0:
- if string[i] == '-':
- stack_with_characters.append('`')
- elif string[i] != '+':
- stack_with_characters.append(string[i])
- elif string[i] == ')':
- while stack_with_characters[-1] != '(':
- math_func(stack_with_characters, stack_with_polynoms)
- stack_with_characters.pop()
- last_is_bracket = True
- elif len(stack_with_characters) == 0:
- if string[i] == ')':
- raise my_exceptions.IncorrectSymbol("incorrect bracket's order ")
- stack_with_characters.append(string[i])
- else:
- while len(stack_with_characters) > 0 and characters[string[i]] <= characters[stack_with_characters[-1]]:
- math_func(stack_with_characters, stack_with_polynoms)
- stack_with_characters.append(string[i])
- if not last_is_bracket:
- last_is_character = True
- else:
- last_is_character = False
- last_is_bracket = False
- i += 1
- while len(stack_with_characters) > 0:
- # try:
- math_func(stack_with_characters, stack_with_polynoms)
- # except my_exceptions.IncorrectSymbol as e:
- # print(e.string)
- # # raise my_exceptions.IncorrectSymbol(e.string)
- # exit(0)
- # except Exception as ex:
- # print(ex)
- # sys.exit(0)
- # raise my_exceptions.IncorrectSymbol("extra characters")
- # print(stack_with_polynoms[0])
- return stack_with_polynoms[0]
- def without_blanks(string):
- '''dels all blanks'''
- lst = []
- lst = [i for i in string if i != ' ']
- return lst
- def witout_missing_multiplications(string):
- '''creates multiplication between characters in string and return list'''
- characters = {'+', '-', '/', '*', '^', '(', ')'}
- numbers = list("0123456789")
- lst = []
- for i, x in enumerate(string):
- if i > 0 and x in numbers and string[i - 1] in numbers:
- lst[len(lst) - 1] = lst[len(lst) - 1] + x
- elif i > 0 and ((x == '(' and string[i - 1] not in characters) or
- (string[i - 1] == ')' and x not in characters) or
- (x == '(' and string[i - 1] == ')') or
- (x not in characters and string[i - 1] not in characters)):
- lst.append('*')
- lst.append(x)
- else:
- lst.append(x)
- # print(lst)
- return lst
- def initial_movements(polynom):
- '''prepares string for compare and checks'''
- polynom = without_blanks(polynom)
- polynom = witout_missing_multiplications(polynom)
- # try:
- # # polynom = correct_division(polynom)
- # except Exception as exc:
- # print(exc.string)
- # sys.exit(0)
- try:
- polynom = canonical_form(polynom)
- except my_exceptions.IncorrectSymbol as e:
- print(e.string)
- sys.exit(1)
- except my_exceptions.IncorrectSymbol as e:
- print(e.string)
- # raise my_exceptions.IncorrectSymbol(e.string)
- exit(0)
- except IndexError as exc:
- try:
- print(exc.string)
- except AttributeError:
- print('extra characters')
- sys.exit(0)
- except Exception as exc:
- # print(exc.string)
- sys.exit(0)
- return polynom
- def compare(first_polynom, second_polynom):
- '''compare 2 polynoms'''
- for x in first_polynom:
- if x not in second_polynom or float(first_polynom[x]) != float(second_polynom[x]):
- if float(first_polynom[x]) != 0.0:
- return "Sadness... Trey are different."
- for x in second_polynom:
- if x not in first_polynom or float(first_polynom[x]) != float(second_polynom[x]):
- if float(second_polynom[x]) != 0.0:
- return "Sadness... Trey are different."
- return "Wow, good polynoms. Trere are similar."
- def write_canon_form(polynom):
- line = ''
- for i in polynom:
- if polynom[i] == int(polynom[i]):
- polynom[i] = int(polynom[i])
- if polynom[i] == 1 and i != '':
- line += i
- line += '+'
- elif polynom[i] == 0:
- pass
- else:
- line += (str(polynom[i]) + i)
- line += '+'
- return(line[:-1])
- def parse_args():
- '''parses arguments'''
- parser = argparse.ArgumentParser(prefix_chars='-/')
- parser.add_argument('first_polynom', help="write one of the polynoms", type=str, nargs=1)
- parser.add_argument('second_polynom', help="write one of the polynoms", type=str, nargs=1)
- parser.add_argument('-cf', help="print canonical form", nargs='?', default='')
- return parser.parse_args()
- if __name__ == "__main__":
- ARGS = parse_args()
- FIRST_POLYNOM = initial_movements(ARGS.first_polynom[0])
- SECOND_POLYNOM = initial_movements(ARGS.second_polynom[0])
- if ARGS.cf != '':
- print(write_canon_form(FIRST_POLYNOM))
- print(write_canon_form(SECOND_POLYNOM))
- print(compare(FIRST_POLYNOM, SECOND_POLYNOM))
Advertisement
Add Comment
Please, Sign In to add comment