(Python) Subroutine: procedure e funzioni - 1


Sottoroutine

Una subroutine è una parte separata del programma che ha un nome e risolve il proprio compito separato. La subroutine si trova all'inizio del programma principale e può essere lanciata (chiamata) dal programma principale specificandone il nome.

L'utilizzo delle subroutine consente di evitare la duplicazione del codice, se è necessario scrivere lo stesso codice in punti diversi del programma. 
Le librerie che vengono importate in un programma (per esempio, la libreria matematica math) consistono in subroutine che sono già state compilate da qualcuno. I programmatori non hanno bisogno di pensare a quali algoritmi implementano, ma semplicemente li applicano, pensando solo a cosa stanno facendo esattamente. Questo è un grande risparmio di tempo. Non è necessario scrivere un algoritmo che è già stato scritto da qualcun altro.

Ogni subroutine dovrebbe eseguire solo un compito,  puoi semplicemente calcolare qualcosa, o generare alcuni dati o fare qualcos'altro. 

Esistono due tipi di subroutine: procedure e funzioni.

Le sottoprocedure eseguono alcune azioni, come la visualizzazione di un risultato sullo schermo in una certa forma (un semplice esempio, l'istruzione print() è una sottoprocedura standard che stampa i dati sullo schermo).

Le subroutine delle funzioni restituiscono un risultato (numero, stringa di caratteri, ecc.) che possiamo utilizzare nel programma principale.

Proviamo a scrivere una semplice procedura:
Supponiamo di dover visualizzare sullo schermo la stringa "Errore". ogni volta che può verificarsi un errore nel codice per colpa dell'utente, ad esempio quando inserisce dati errati.
Questo può essere fatto scrivendo la dichiarazione print("Errore") E ora immagina che una riga del genere debba essere inserita in molti punti del programma. Certo, puoi semplicemente scriverlo ovunque. Ma questa soluzione ha due inconvenienti.
1) Questa stringa verrà memorizzata molte volte.
2) Se vogliamo modificare l'output in caso di errore, dovremo modificare questa riga in tutto il programma, il che è piuttosto scomodo

Per tali casi, sono necessarie procedure.
Un programma con una procedura potrebbe avere questo aspetto:
  def printError(): # descrizione della procedura print("Errore") ... printError() # avvia la procedura per l'esecuzione. # Basta specificare il nome della procedura che vogliamo eseguire ... stampaErrore()
Devi ricordare!
  1. La procedura inizia con la parola def (dall'inglese - define - definire). Dopo il nome della procedura, vengono scritte parentesi vuote e due punti . I parametri possono essere specificati all'interno delle parentesi (ne parleremo più avanti).
  2. Tutte le istruzioni eseguite in una procedura sono rientrate. 
  3. Per eseguire una procedura, nel programma principale devi chiamarla per nome e ricordarti di scrivere le parentesi!
  4. Puoi chiamare una procedura in un programma tutte le volte che vuoi.

Parametri e argomenti

Immaginiamo ora di dover visualizzare messaggi diversi in risposta all'errore di un utente, a seconda del tipo di errore commesso.
In questo caso, puoi scrivere la tua procedura per ogni errore:  
def stampaErroreZero():
    print("Errore. Divisione per zero!")
def printErrorInput():
    print("Errore nell'inserimento!")

E se ci sono molti più possibili errori? Questa soluzione non fa per noi!
Dobbiamo imparare a controllare la procedura dicendole quale messaggio di errore visualizzare.
Per fare ciò, abbiamo bisogno di parametri che scriveremo tra parentesi dopo il nome della procedura
def printError(s):
    print("s")

In questa procedura, s è un parametro, una variabile speciale che consente di controllare la procedura.
 
Il parametro è una variabile che determina come funziona la subroutine. I nomi dei parametri sono separati da virgole nell'intestazione della subroutine.


Ora, quando si chiama la procedura, bisogna indicare tra parentesi il valore effettivo che verrà assegnato al parametro (variabile s) all'interno della nostra procedura
printError("Errore! Divisione per zero!")

Tale valore è chiamato argomento.
 
L'argomento è il valore del parametro che viene passato alla subroutine quando viene chiamata.

Un argomento può essere non solo un valore costante, ma anche una variabile o un'espressione aritmetica.

Variabili locali e globali

Le variabili che vengono introdotte nel programma principale sono chiamate globali (o condivise).

Puoi accedere alle variabili globali da qualsiasi subroutine. 

Spesso è necessario introdurre variabili aggiuntive che verranno utilizzate solo nella subroutine. Tali variabili sono chiamate locali (o locali). Puoi lavorare con loro solo all'interno della subroutine in cui sono creati. Il resto delle routine non "sa" nulla di esse.

Pertanto, è possibile limitare l'ambito (ambito) di una variabile solo alla subroutine in cui è realmente necessario. In programmazione, questa tecnica è chiamata incapsulamento  - nascondere la variabile dall'essere modificata dall'esterno.

Analizza tre programmi:
Descrizione Programma
1) In questo programma, la variabile i è locale. Se non c'è nessuna variabile i nel programma principale, avremo un messaggio di errore. E se esiste una tale variabile (allora è una variabile globale), il suo valore viene visualizzato sullo schermo.
prova def():
    stampa(i)
2) Qui, anche se c'è una variabile globale i, verrà creata una nuova variabile locale i con un valore di 2, e 2 apparirà sul schermo.
prova def():
  io = 2
    stampa(i)
3) In questo programma è presente una variabile globale i con valore 15. Il suo valore può essere modificato all'interno della subroutine, per questo è necessario dichiarare esplicitamente che è globale ( usa il comando global ).
La procedura funzionerà con la variabile globale i e le verrà assegnato un nuovo valore di 2. Viene visualizzato il valore 2.
prova def():
  globale i
    io = 2
    
# programma principale
io = 15
stampa(io)