Albero ricorsivo

Disegnare l'albero, 16 anni dopo

by

Non ricordo con quale versione di Basic realizzai per la prima volta il disegno ricorsivo di un albero, poi ripreso in excel per il mio primo post sul blog Elaborando. Comunque era un Basic senza ricorsività nativa.
Per tracciare i vari livelli di ramificazione dell'albero, quindi, creai una primitiva struttura di ricorsività ad hoc sulla chiamata a subroutine del Basic.

Vecchio post su Elaborando


E se volessi ridisegnare oggi l'albero? Vediamo quali diventano le scelte:

  • linguaggio --> Python
  • modulo di grafica --> Turtle
  • sistema di sviluppo --> replit.com

e le relative motivazioni.

Python

È un linguaggio semplice da apprendere e da utilizzare, su qualunque piattaforma.
Si può optare per l'installazione sul proprio pc (o Mac), oppure per l'utilizzo di una delle piattaforme web di collaborazione.
Esempio: Google Colaboratory, Cocalc, Replit.

Turtle

La tartaruga (turtle) è la metafora utilizzata  per descrivere l'utilizzo della grafica nel linguaggio Logo. Creato nel 1967, è stato largamente utilizzato in ambito educativo: una tartaruga lascia una traccia sullo schermo, muovendosi secondo direttive del tipo ruota, avanza, arretra.

Replit

Perché Replit? Il Google Colaboratory ha una propria versione di Turtle, e su Cocalc mi sono fermato alle prime difficoltà nell'importare il modulo Turtle.
Escluso per pigrizia di installare il modulo sul mio Mac, mi rimaneva Replit, con account gratuito.
La velocità non è entusiasmante, ma va bene per lo scopo amarcord dell'operazione.

Il programma

La struttura del programma è abbastanza semplice:

  1. import del modulo turtle;
  2. la funzione che traccia ricorsivamente le fronde dell'albero;
  3. la definizione dei parametri che configurano l'albero (dimensioni, colori, livelli e numerosità di ramificazione);
  4. il blocco principale, che disegna il tronco e chiama la funzione che traccia le fronde;
  5. export del disegno dell'albero.

Il risultato è riportato nell'immagine del post.

I dettagli

L'import del modulo turtle è banale:

from turtle import *

Lasciando da parte per un momento la funzione di tracciamento dell'albero, vediamo la sezione di configurazione dei parametri dell'albero:

size, resize = 120, 1.3
pensize(1.5)
rot = [-45,-15,20,40]
color_list = ['darkgoldenrod','goldenrod','pink']
level = 5

Il parametro size determina la lunghezza in pixel della base dell'albero. Ogni successivo livello di ramificazione ha una lunghezza scalata progressivamente in riduzione da size secondo il fattore resize.

Pensize determina lo spessore del tratto che traccia l'albero, mentre la lista rot elenca gli angoli di deviazione di ciascuna diramazione, rispetto alla direzione del ramo genitore. Il numero di diramazioni a ciascun livello è quindi dato semplicemente dal numero di elementi nella lista rot.

La lista color_list descrive i colori da applicare rispettivamente alla base dell'albero, ai rami dei livelli successivi, all'ultimo livello. I colori seguono la definizione standard, che può essere consultata sul sito del World Wide Web Consortium (W3C).

La funzione ricorsiva di tracciamento dell'albero

La funzione branch() riceve in ingresso il livello di diramazione da tracciare e la dimensione dei rami, oltre al parametro globale resize. Sono implicitamente globali anche le liste, poiché in Python questo tipo di variabile è passato alle funzioni mediante riferimento e non mediante valore. Le liste in questione sono due: color_list e rot.

Il funzionamento della funzione è abbastanza semplice: se si sono esauriti i livelli richiesti, la funzione ritorna al chiamante senza fare nulla. Altrimenti adegua il colore e traccia, dal punto in cui si trova la tartaruga, un mini albero, chiamando sé stessa.

def branch(level,size):
  global resize
  if level == 0:
      return (True)
  else:
    curr_color = color()[0]
    if level == 1:
      color(color_list[-1])
    else:
      color(color_list[1])
    for i in rot:
      right(i)
      forward(size)
      branch(level-1,size/resize)
      backward(size)
      left(i)
    color(curr_color)
    return(True)

Il corpo centrale del programma

In questa sezione di codice si predispone lo stato della tartaruga (non visibile e che punta verso il bordo superiore del foglio), si traccia la base dell'albero e poi si chiama la funzione che, ricorsivamente, si occuperà di tracciare l'intero albero.

hideturtle()
color(color_list[0])
left(90)
penup()
sety(-size*resize)
pendown()
forward(size)
branch(level,size/resize)

Infine, l'export dell'immagine tracciata

getscreen().getcanvas().postscript(file='albero.ps')

Riducendo a 3 il numeero di livelli dell'albero, si comprende forse meglio il comportamento del programma.

Albero ricorsivo su 3 livelli

Come giocare con il codice

Il modo più semplice per mettere le mani sul codice e sperimentare è quello di ricreare l'ambiente in cui l'ho sviluppato. Quindi:

  • registrare un account gratuito su replit.com; 
  • creare un progetto vuoto;
  • copia-incollare i pezzi di codice appena riportati, seguendo la sequenza numerata riportata nel punto Il programma;
  • run!

In alternativa è possibile scaricare il codice del programma in formato compresso da qui.

Nota: articolo pubblicato più o meno un anno fa su Wix.com.

Pasquale

Dopo innumerevoli anni da informatico, tra Ivrea e Milano, finalmente a riposo sulle rive del lago di Lecco. Scrivimi a: 70plus@libero.it