Menu
Coddy logo textTech

Struttura ricorsiva

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

Il vero potere della struttura che abbiamo visto nella lezione precedente si manifesta con la ricorsione.

Considera un calcolo con più di un operatore, per esempio:

  • 2 + 3 * 4 + 5

Secondo le regole matematiche, c’è un ordine: per prima cosa dobbiamo calcolare 3 * 4 e poi tutto il resto.

Il calcolo seguente può essere formattato in una struttura ricorsiva nei seguenti modi:

  • ['+', ['+', 2, ['*', 3, 4]], 5]
  • ['+', 2, ['+', 5, ['*', 3, 4]]]
  • ['+', 5, ['+', ['*', 3, 4], 2]]

Nota che la struttura semplice più profonda è sempre ['*', 3, 4], che è la prima da calcolare. Nota anche che tutto segue la struttura di base [op, num1, num2]. 

Altri esempi di calcoli convertiti in strutture ricorsive:

  • 2 - 3  ->  ['-', 2, 3]
  • 1 - 2 + 3  ->  ['+', ['-', 1, 2], 3]
  • 1 * 2 - 3  ->  ['-', ['*', 1, 2], 3]
  • 2.3 + 3 / 4.2 - 2  ->  ['-', ['+', 2.3, ['/', 3, 4.2]], 2]
challenge icon

Sfida

Medio

Aggiorna la funzione eval per supportare strutture ricorsive come descritto sopra.

Note:

  • chiama la funzione calc quando la struttura è semplice: un operatore con due numeri .
  • chiama ricorsivamente eval se uno degli argomenti è un'altra struttura (lista).

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):
    op = lst[0]
    n1 = lst[1]
    n2 = lst[2]
    return calc(op, n1, n2)

Tutte le lezioni di Progetto di calcolatrice con Python

Esercitati da solo: Compilatore Python online