Wacky_rubia

polynoms

Sep 13th, 2015
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.87 KB | None | 0 0
  1. #!/usr/bin/python3
  2. '''this programm compare 2 polynoms'''
  3. import sys
  4. import re
  5. import argparse
  6. import my_exceptions
  7.  
  8.  
  9. def sort_by_alphabet(string):
  10.     '''sorts string by alphabet'''
  11.     lst = list(string)
  12.     lst.sort(key=lambda x: x[0])
  13.     return ''.join(lst)
  14.  
  15.  
  16. def add(first_polynom, second_polynom):
  17.     '''adds 2 monomial defined in dictionary format'''
  18.     for x in second_polynom:
  19.         if x in first_polynom:
  20.             first_polynom[x] += second_polynom[x]
  21.         else:
  22.             first_polynom[x] = second_polynom[x]
  23.     return first_polynom
  24.  
  25.  
  26. def multiplication(first_polynom, second_polynom):
  27.     '''multiplies 2 monomial defined in dictionary format'''
  28.     current_poly = {}
  29.     for x in first_polynom:
  30.         for y in second_polynom:
  31.             key = sort_by_alphabet(x+y)
  32.             value = float(first_polynom[x]) * float(second_polynom[y])
  33.             if key in current_poly:
  34.                 current_poly[key] += value
  35.             else:
  36.                 current_poly[key] = value
  37.     return current_poly
  38.  
  39.  
  40. def degree(first_polynom, second_polynom):
  41.     '''elevates the degre using multiplication'''
  42.     f = {}
  43.     for i in first_polynom:
  44.         if first_polynom[i] == 0.0:
  45.             if '' not in f:
  46.                 f[''] = 0.0
  47.         else:
  48.             f[i] = first_polynom[i]
  49.     first_polynom = f
  50.     f2 = {}
  51.     for i in second_polynom:
  52.         if second_polynom[i] == 0.0:
  53.             if '' not in f2:
  54.                 f2[''] = 0.0
  55.         else:
  56.             f2[i] = second_polynom[i]
  57.     second_polynom = f2
  58.     if '' not in second_polynom or len(second_polynom) > 1:
  59.         raise my_exceptions.IncorrectSymbol("incorrect degree")
  60.     deg = second_polynom['']
  61.     # print(deg)
  62.     # if len(first_polynom) == 1:
  63.     #     for i in first_polynom:
  64.     #         if first_polynom[i] == 0.0:
  65.     #             if deg == 0.0:
  66.     #                 raise my_exceptions.Incorre
  67.     if '' in first_polynom and len(first_polynom) == 1 and deg <= 0:
  68.         if deg == 0:
  69.             if first_polynom[''] == 0.0:
  70.                 raise my_exceptions.IncorrectSymbol("неопределенная степень")
  71.             return {'': 1}
  72.         if first_polynom[''] == 0:
  73.             raise my_exceptions.IncorrectSymbol("ноль в отрицательную степень")
  74.         return {'': 1/degree(first_polynom, {'': -deg})['']}
  75.     if float(deg) != int(deg) or int(deg) < 0:
  76.         raise my_exceptions.IncorrectSymbol("nonintegral degree")
  77.     deg = int(deg)
  78.     current_poly = multiplication(first_polynom, {'': 1})
  79.     for _ in range(deg - 1):
  80.         current_poly = multiplication(current_poly, first_polynom)
  81.     if deg == 0:
  82.         current_poly = {'': 1}
  83.     return current_poly
  84.  
  85.  
  86. def division(first_polynom, second_polynom):
  87.     '''check correct division'''
  88.     new_polynom = {}
  89.     if (len(second_polynom) > 1):
  90.         raise my_exceptions.IncorrectSymbol("incorrect division")
  91.     for i in second_polynom:
  92.         for j in first_polynom:
  93.             if i != '' and i not in list(j):
  94.                 raise my_exceptions.IncorrectSymbol("variable in divisor")
  95.             else:
  96.                 value = first_polynom[j]
  97.                 j = j.replace(i, '')
  98.                 new_polynom[j] = value
  99.                 second_polynom = { '' : second_polynom[i] }
  100.     first_polynom = new_polynom
  101.     if float(second_polynom['']) == 0.0:
  102.         raise my_exceptions.IncorrectSymbol("деление на ноль")
  103.     divisor = second_polynom['']
  104.     for dividend in first_polynom:
  105.         first_polynom[dividend] = first_polynom[dividend] / float(divisor)
  106.     return first_polynom
  107.  
  108.  
  109. def new_polynom(string, i, stack_with_polynoms, numbers, characters):
  110.     '''creates polynom from list of characters and list of monomial'''
  111.     value = 1
  112.     key = ''
  113.     while i < len(string) and string[i] not in characters:
  114.         if re.match(numbers, string[i]):
  115.             value *= float(string[i])
  116.         else:
  117.             key += string[i]
  118.         i += 1
  119.     #if value == 0:
  120.     #    value = 1
  121.     stack_with_polynoms.append({sort_by_alphabet(key): value})
  122.     return i - 1
  123.  
  124.  
  125. def math_func(stack_with_characters, stack_with_polynoms):
  126.     '''select math function'''
  127.     character = stack_with_characters.pop()
  128.     second_operand = stack_with_polynoms.pop()
  129.     if character == '`':
  130.         stack_with_polynoms.append(multiplication(second_operand, {'': -1}))
  131.         return
  132.     first_operand = stack_with_polynoms.pop()
  133.     if character == '-':
  134.         stack_with_polynoms.append(add(first_operand, multiplication(second_operand, {'': -1})))
  135.     elif character == '+':
  136.         stack_with_polynoms.append(add(first_operand, second_operand))
  137.     elif character == '*':
  138.         stack_with_polynoms.append(multiplication(first_operand, second_operand))
  139.     elif character == '^':
  140.         stack_with_polynoms.append(degree(first_operand, second_operand))
  141.     elif character == '/':
  142.         stack_with_polynoms.append(division(first_operand, second_operand))
  143.  
  144.  
  145. def canonical_form(string):
  146.     '''main function which makes dict from list'''
  147.     characters = {'`': 5, '(': 0, ')': 1, '+': 2, '-': 2, '*': 3, '/': 3, '^': 4}
  148.     correct_symbols = r'[+*\-/()\w^.]'
  149.     numbers = r'[\d.]'
  150.     length = len(string)
  151.     stack_with_polynoms = []
  152.     stack_with_characters = []
  153.     last_is_character = True
  154.     last_is_bracket = False
  155.     i = 0
  156.     while i < length:
  157.         if not re.match(correct_symbols, string[i]):
  158.             raise my_exceptions.IncorrectSymbol("you wrote incorrect symbol")
  159.         if string[i] not in characters:
  160.             i = new_polynom(string, i, stack_with_polynoms, numbers, characters)
  161.             last_is_character = False
  162.         else:
  163.             if last_is_character or i == 0:
  164.                 if string[i] == '-':
  165.                     stack_with_characters.append('`')
  166.                 elif string[i] != '+':
  167.                     stack_with_characters.append(string[i])
  168.             elif string[i] == ')':
  169.                 while stack_with_characters[-1] != '(':
  170.                     math_func(stack_with_characters, stack_with_polynoms)
  171.                 stack_with_characters.pop()
  172.                 last_is_bracket = True
  173.             elif len(stack_with_characters) == 0:
  174.                 if string[i] == ')':
  175.                     raise my_exceptions.IncorrectSymbol("incorrect bracket's order ")
  176.                 stack_with_characters.append(string[i])
  177.             else:
  178.                 while len(stack_with_characters) > 0 and characters[string[i]] <= characters[stack_with_characters[-1]]:
  179.                     math_func(stack_with_characters, stack_with_polynoms)
  180.                 stack_with_characters.append(string[i])
  181.             if not last_is_bracket:
  182.                 last_is_character = True
  183.             else:
  184.                 last_is_character = False
  185.             last_is_bracket = False
  186.         i += 1
  187.     while len(stack_with_characters) > 0:
  188.         # try:
  189.         math_func(stack_with_characters, stack_with_polynoms)
  190.         # except my_exceptions.IncorrectSymbol as e:
  191.         #     print(e.string)
  192.         #     # raise my_exceptions.IncorrectSymbol(e.string)
  193.         #     exit(0)
  194.         # except Exception as ex:
  195.         #     print(ex)
  196.         #     sys.exit(0)
  197.             # raise my_exceptions.IncorrectSymbol("extra characters")
  198.     # print(stack_with_polynoms[0])
  199.     return stack_with_polynoms[0]
  200.  
  201.  
  202. def without_blanks(string):
  203.     '''dels all blanks'''
  204.     lst = []
  205.     lst = [i for i in string if i != ' ']
  206.     return lst
  207.  
  208.  
  209. def witout_missing_multiplications(string):
  210.     '''creates multiplication between characters in string and return list'''
  211.     characters = {'+', '-', '/', '*', '^', '(', ')'}
  212.     numbers = list("0123456789")
  213.     lst = []
  214.     for i, x in enumerate(string):
  215.         if i > 0 and x in numbers and string[i - 1] in numbers:
  216.             lst[len(lst) - 1] = lst[len(lst) - 1] + x
  217.         elif i > 0 and ((x == '(' and string[i - 1] not in characters) or
  218.             (string[i - 1] == ')' and x not in characters) or
  219.             (x == '(' and string[i - 1] == ')') or
  220.             (x not in characters and string[i - 1] not in characters)):
  221.             lst.append('*')
  222.             lst.append(x)
  223.         else:
  224.             lst.append(x)
  225.     # print(lst)
  226.     return lst
  227.  
  228.  
  229. def initial_movements(polynom):
  230.     '''prepares string for compare and checks'''
  231.     polynom = without_blanks(polynom)
  232.     polynom = witout_missing_multiplications(polynom)
  233.     # try:
  234.     #     # polynom = correct_division(polynom)
  235.     # except Exception as exc:
  236.     #     print(exc.string)
  237.     #     sys.exit(0)
  238.     try:
  239.         polynom = canonical_form(polynom)
  240.     except my_exceptions.IncorrectSymbol as e:
  241.         print(e.string)
  242.         sys.exit(1)
  243.     except my_exceptions.IncorrectSymbol as e:
  244.             print(e.string)
  245.             # raise my_exceptions.IncorrectSymbol(e.string)
  246.             exit(0)
  247.     except IndexError as exc:
  248.         try:
  249.             print(exc.string)
  250.         except AttributeError:
  251.             print('extra characters')
  252.         sys.exit(0)
  253.     except Exception as exc:
  254.         # print(exc.string)
  255.         sys.exit(0)
  256.     return polynom
  257.  
  258.  
  259. def compare(first_polynom, second_polynom):
  260.     '''compare 2 polynoms'''
  261.     for x in first_polynom:
  262.         if x not in second_polynom or float(first_polynom[x]) != float(second_polynom[x]):
  263.             if float(first_polynom[x]) != 0.0:
  264.                 return "Sadness... Trey are different."
  265.     for x in second_polynom:
  266.         if x not in first_polynom or float(first_polynom[x]) != float(second_polynom[x]):
  267.             if float(second_polynom[x]) != 0.0:
  268.                 return "Sadness... Trey are different."
  269.     return "Wow, good polynoms. Trere are similar."
  270.  
  271.  
  272. def write_canon_form(polynom):
  273.     line = ''
  274.     for i in polynom:
  275.         if polynom[i] == int(polynom[i]):
  276.             polynom[i] = int(polynom[i])
  277.         if polynom[i] == 1 and i != '':
  278.             line += i
  279.             line += '+'
  280.         elif polynom[i] == 0:
  281.             pass
  282.         else:
  283.             line += (str(polynom[i]) + i)
  284.             line += '+'
  285.     return(line[:-1])
  286.  
  287.  
  288. def parse_args():
  289.     '''parses arguments'''
  290.     parser = argparse.ArgumentParser(prefix_chars='-/')
  291.     parser.add_argument('first_polynom', help="write one of the polynoms", type=str, nargs=1)
  292.     parser.add_argument('second_polynom', help="write one of the polynoms", type=str, nargs=1)
  293.     parser.add_argument('-cf', help="print canonical form", nargs='?', default='')
  294.     return parser.parse_args()
  295.  
  296. if __name__ == "__main__":
  297.     ARGS = parse_args()
  298.     FIRST_POLYNOM = initial_movements(ARGS.first_polynom[0])
  299.     SECOND_POLYNOM = initial_movements(ARGS.second_polynom[0])
  300.     if ARGS.cf != '':
  301.         print(write_canon_form(FIRST_POLYNOM))
  302.         print(write_canon_form(SECOND_POLYNOM))
  303.     print(compare(FIRST_POLYNOM, SECOND_POLYNOM))
Advertisement
Add Comment
Please, Sign In to add comment