Hard 2 варианта

← разместить еще код

Расшаренный код:

def get_result(formula):
    operation_dict = {
        'sub': ' - ',
        'add': ' + '
    }

    def get_main_operation(condition):
        if condition.find(' - ') > 0:
            return 'sub'
        if condition.find(' + ') > 0:
            return 'add'
        return False



    operator = get_main_operation(formula)

    if operator:
        operands =  formula.split(operation_dict[operator])
        operand_list = []
        #есть ли целая часть
        for operand in operands:
            full = 0
            if ' ' in operand:
                full = int(operand.split(' ')[0])
                operand = operand.split(' ')[1]

            if '/' in operand:
                muls = list(map(int,operand.split('/')))
            else:
                muls = [int(operand),1]
                full = 0

            operand_list.append({
                'full':full,
                'operand':operand,
                'muls': muls
            })


        val_1 = operand_list[0]['full'] + operand_list[0]['muls'][0] / operand_list[0]['muls'][1]
        val_2 = operand_list[1]['full'] + operand_list[1]['muls'][0] / operand_list[1]['muls'][1]

        formula_result = eval(str(val_1) + operation_dict[operator] + str(val_2))

        new_full_part = int(formula_result)
        new_dec_part = formula_result - int(formula_result)

        mul2 = operand_list[0]['muls'][1] * operand_list[1]['muls'][1]
        mul1 = round(new_dec_part * mul2)

        result_string = '';

        if new_full_part != 0:
            result_string = str(new_full_part)+' ';

        if mul1 != 0:
            result_string += str(mul1)+'/'+str(mul2)

        return result_string

#заменить на input
print("5/6 + 4/7 =", get_result("5/6 + 4/7"))
print("-2/3 - -2 =", get_result("-2/3 - -2"))
print("4 -2/3 - -2 =", get_result("4 -2/3 - -2"))






# Вывод: 1 1/3

import os


def nod(a, b):   # Ищем НОД
    while b:
        a, b = b, a % b
    return a


def formatout(num):  # Форматируем вывод
    if type(num) is int:
        return num
    if len(num) == 2:
        res = '%s/%s' % (num[0], num[1])
    if len(num) == 3:
        res = '%s %s/%s' % (num[0], num[1], num[2])
    return res


def defract(num):  # Выделяем из дроби целую часть
    if not num[0] % num[1]:
        res = int(num[0] / num[1])
    elif abs(num[0]) > abs(num[1]):
        res = [int(num[0] / num[1]), abs(num[0]) % num[1], num[1]]
        n = nod(abs(res[1]), abs(res[2]))
        if n != 1:
            res[1], res[2] = int(res[1] / n), int(res[2] / n)
    else:
        res = num
        n = nod(abs(res[0]), abs(res[1]))
        if n != 1:
            res[0], res[1] = int(res[0] / n), int(res[1] / n)
    return res


def fract(num):  # Приводим число к дроби
    if num[0] and num[2]:
        num[1] = (num[0] * num[2] + num[1] if num[0] > 0 else
                  num[0] * num[2] - num[1])
        num[0] = False
    return [n for n in num if n]


def calcfract(*n):  # Вычисляем
    if len(n) == 3:
        sign = n[len(n)-1]
        num1 = fract([n[0]['int'], n[0]['num'], n[0]['dem']])
        num2 = fract([n[1]['int'], n[1]['num'], n[1]['dem']])
        if len(num1) == len(num2):
            if len(num1) == 1:
                res = (num1[0] + num2[0] if sign == '+' else
                       num1[0] - num2[0])
            if len(num1) == 2:
                group = list(zip(num1, num2))
                if group[1][0] == group[1][1]:
                    res = (sum(group[0]) if sign == '+' else
                           group[0][0] - group[0][1])
                    res = [res, group[1][0]]
                else:
                    res = (group[0][0] * group[1][1] +
                           group[0][1] * group[1][0] if sign == '+' else
                           group[0][0] * group[1][1] -
                           group[0][1] * group[1][0])
                    res = [res, group[1][0] * group[1][1]]
        else:
            if sign == '+':
                res = ([num1[0] * num2[1] + num2[0], num2[1]] if
                       len(num1) == 1 else
                       [num2[0] * num1[1] + num1[0], num1[1]])
            if sign == '-':
                res = ([num1[0] * num2[1] - num2[0], num2[1]] if
                       len(num1) == 1 else
                       [-(num2[0] * num1[1] - num1[0]), num1[1]])
    if len(n) == 1:
        res = fract([n[0]['int'], n[0]['num'], n[0]['dem']])
        if len(res) == 1:
            res = res[0]
    if not type(res) is int:
        res = defract(res)
        res = formatout(res)
    print('Ответ: %s' % (res))
    return res


def discharge(li):  # Выделяем части дроби; int: целая часть; num: числитель; dem: знаменатель;
    num = {'int': False, 'num': False, 'dem': False}
    if len(li) == 1:
        num['int'] = int(li[0])
    if len(li) == 2 and ~li[1].find('/'):
        num['int'] = int(li[0])
        num['num'] = int(li[1].split('/')[0])
        num['dem'] = int(li[1].split('/')[1])
    if len(li) == 2 and li[1].isdigit():
        num['num'] = int(li[0])
        num['dem'] = int(li[1])
    return num


def formatin(usr_in):  # Форматируем входную строку
    usr_in = usr_in.strip()
    is_one_operand = False
    sign = False
    plus = usr_in.find(' + ')
    minus = usr_in.find(' - ')

    if not ~minus and not ~plus:
        is_one_operand = True
    else:
        sign = usr_in[minus+1] if ~minus else usr_in[plus+1]
    if is_one_operand:
        oper = (usr_in.split(' ') if ~usr_in.find(' ') else
                usr_in.split('/'))
        num = discharge(oper)
        return calcfract(num)
    else:
        opers = usr_in.split(' ' + sign + ' ')
        oper1 = (opers[0].split(' ') if ~opers[0].find(' ') else
                 opers[0].split('/'))
        oper2 = (opers[1].split(' ') if ~opers[1].find(' ') else
                 opers[1].split('/'))
        num1 = discharge(oper1)
        num2 = discharge(oper2)
        return calcfract(num1, num2, sign)


user_in = input('Введите выражнение: ')
formatin(user_in)