Menu
Coddy logo textTech

Ottieni un numero

Lezione 18 di 29 del corso Progetto di calcolatrice con Python di Coddy.

Ora vogliamo analizzare una stringa per trasformarla in una rappresentazione sotto forma di lista che eval possa ricevere come input.

Ad esempio, 32 +12* 4 dovrebbe essere analizzato e trasformato in ['+', 32, ['*', 12, 4]]

Iniziamo con una funzione di supporto che ci sarà utile nella funzione principale di analisi.

challenge icon

Sfida

Facile

Crea una funzione get_next che riceve una stringa senza spazi e un numero, l’indice iniziale nella stringa, e restituisce il numero o l’operatore successivo.

Questa volta occupati solo dei numeri.

Esempi:

  • get_next('32+12*4', 0)  ->  32
  • get_next('1.2*3.54', 4)  ->  3.54
  • get_next('3/56-2', 3)  ->  6

Puoi supporre che l’indice iniziale si trovi su un numero.

Nota: esistono due tipi di numeri, int o float.

Assicurati di restituire un numero di tipo int o float, non str!

Provalo tu

def calc(op, n1, n2=None):
    if not isinstance(n1, int) and not isinstance(n1, float):
        raise Exception('Invalid number "' + str(n1) + '"')

    if n2 is None:
        if op == '+' or op == 'add':
            return n1
        if op == '-' or op == 'sub':
            return -n1

        raise Exception('Invalid operator "' + op + '"')

    if not isinstance(n2, int) and not isinstance(n2, float):
        raise Exception('Invalid number "' + str(n2) + '"')

    if op == '+' or op == 'add':
        return n1 + n2
    if op == '-' or op == 'sub':
        return n1 - n2
    if op == '*' or op == 'mul':
        return n1 * n2
    if op == '/' or op == 'div':
        if n2 == 0:
            raise Exception("Division by zero")
        return n1 / n2
    if op == '%' or op == 'mod':
        if n2 == 0:
            raise Exception("Division by zero")
        return n1 % n2
    if op == '^' or op == 'pow':
        return n1 ** n2

    raise Exception('Invalid operator "' + op + '"')


def eval(lst):
    if not isinstance(lst, list):
        raise Exception('Failed to evaluate "' + str(lst) + '"')
    if len(lst) == 2:
        op = lst[0]
        n = lst[1]
        if not isinstance(n, list):
            return calc(op, n)

        if isinstance(n, list):
            n = eval(n)

        return calc(op, n)
    elif len(lst) == 3:
        op = lst[0]
        n1 = lst[1]
        n2 = lst[2]
        if not isinstance(n1, list) and not isinstance(n2, list):
            return calc(op, n1, n2)
        
        if isinstance(n1, list):
            n1 = eval(n1)
        if isinstance(n2, list):
            n2 = eval(n2)

        return calc(op, n1, n2)
    else:
        raise Exception('Failed to evaluate "' + str(lst) + '"')


LEVEL_TWO_OPERATORS = ['+', '-', 'add', 'sub']
LEVEL_ONE_OPERATORS = ['*', '/', '%', 'mul', 'div', 'mod']
FUNCTIONS_OPERATORS = ['^', 'pow']
def struct(lst):
    if not isinstance(lst, list) or len(lst) <= 1:
        raise Exception('Failed to structure "' + str(lst) + '"')

    if len(lst) == 2:
        return lst

    lst_cpy = lst
    operators_groups = [FUNCTIONS_OPERATORS, LEVEL_ONE_OPERATORS, LEVEL_TWO_OPERATORS, 'all']
    for operators_group in operators_groups:
        i = 0
        while i < len(lst):
            if (not isinstance(lst[i], int) and not isinstance(lst[i], float) and not isinstance(lst[i], list)) if operators_group == 'all' else (lst[i] in operators_group):
                if len(lst) - 1 == i:
                    raise Exception('Failed to structure "' + str(lst_cpy) + '"')
                if len(lst) == 3:
                    return [lst[i], lst[i - 1], lst[i + 1]]
                temp = lst[:i - 1]
                temp.append([lst[i], lst[i - 1], lst[i + 1]])
                temp += lst[i + 2:]
                lst = temp
            else:
                i += 1
    return lst

Tutte le lezioni di Progetto di calcolatrice con Python

Esercitati da solo: Compilatore Python online