Ripetere istruzioni

Come far stare mille comandi in una riga di codice.

I computer attuali eseguono milioni o miliardi di istruzioni al secondo, ma se devo scrivere esplicitamente ogni istruzione che deve eseguire, impiego secoli e secoli per scrivere un programma. Se voglio che un programma stampi 3 volte di seguito una frase posso scrivere:

>>> print "ciao a tutti"; print "ciao a tutti"; print "ciao a tutti";
ciao a tutti
ciao a tutti
ciao a tutti

oppure posso usare un’istruzione che produce un ciclo:

>>> for cont in range(3):
                print "ciao a tutti"


ciao a tutti
ciao a tutti
ciao a tutti

Alcune osservazioni:

  1. L’istruzione for ... non è molto più sintetica dei 3 comandi messi di seguito. Ma se dovessi stampare 1000 volte la frase, col primo metodo la faccenda diventerebbe complicata e noiosa, mentre con l’istruzione for ... mi basterebbe cambiare un numero:

    for cont in range(1000): ...
    
  2. L’istruzione va capita, partiamo dal fondo:

    1. range(1000) fornisce, una lista che contiene gli interi da 0 a 999 (1000 numeri),
    2. uno alla volta, i numeri contenuti nella lista prodotta da range, viene messo nella variabile cont ...
    3. e per ogni valore di cont viene eseguito il blocco di codice che segue il simbolo “:”
  3. La sintassi è:

    for <variabile> in range(<numero>):
        <istruzioni>
    
  4. L’istruzione for ripete tutte le istruzioni che la seguono e che sono indentate, cioè rientrate di alcuni spazi rispetto all’istruzione stessa.

  5. In Python le righe di codice consecutive che iniziano alla stessa colonna, formano un blocco di codice.

  6. Se avviamo un ciclo troppo lungo e vogliamo interromperlo possiamo premere il tasto: <Ctrl-c>.

  7. Il tipo di struttura informatica prodotta dal comando for si chiama iterazione.

Proviamo ad esplorare il significato della variabile che segue l’istruzione for, a cosa può servite? Iniziamo a provare il comando:

>>> for cont in range(5):
                print cont


0
1
2
3
4

Possiamo farci stampare una tabella di quadrati e cubi:

>>> for num in range(11):
        print "%s  %s  %s" % (num, num*num, num*num*num)

ma i numeri sono allineati male. Prova questa variante:

>>> for num in range(5):
        print "%5s  %5s  %5s" % (num, num*num, num*num*num)

Che significato ha il numero inserito nel segnaposto? E per vedere i reciproci dei numeri precedenti? Ovviamente (?!) non posso partire da 0, ma da 1. Devo anche stare attento alle espressioni: 1/i*i non è lo stesso di 1/(i*i). Poiché sia 1 che i sono valori interi, Python tronca il risultato eliminando i decimali. Un modo per risolvere i problemi precedenti è:

>>> for n in range(1, 5):
        print "%10s  %10s  %10s" %(1./n, 1./(n*n), 1./(n*n*n))

Riassumendo

  • Possiamo far ripetere a Python un blocco di codice usando l’istruzione for.

  • Un blocco di codice si riconosce perché è formato da istruzioni consecutive che iniziano in modo allineato, sulla stessa colonna.

  • La sintassi dell’istruzione for è:

    for <variabile> in range(<numero>):
        <bloco di istruzioni>
    
  • La variabile del ciclo contiene, ad ogni ciclo, un numero intero successivo da 0 a <numero> escluso.

  • range può avere due parametri in questo caso la variabile va dal primo all’ultimo escluso.

Prova tu

  1. La formattazione dell’ultimo esempio, fa un po’ schifo... prova con quest’altra stringa: “%10.5f %10.5f %10.5f”
  2. Quali altri caratteri di formattazione sono riconosciuti da Python?
  3. Scrivi un ciclo che stampi per ogni numero da 0 a 20: il numero stesso, il suo doppio il suo triplo e il suo quadruplo, in modo che risultino allineati.
  4. Metti in una variabile, “n” un numero. Scrivi il ciclo che stampi i suoi primi 15 multipli.
  5. Scrivi un ciclo che stampi i multipli di un numero senza andare a capo.
  6. Scrivi un ciclo che stampi i multipli di 7 ma solo dal 35° multiplo al 43°.
  7. Un ciclo può contenere altri cicli annidati... Scrivi il comando che stampi la tabellina pitagorica.