#!/usr/bin/env python3 # -*- coding: utf-8 -*- # importo il valore (approssimato) di Pi greco dal modulo math from math import pi def area_cerchio(raggio): "Calcolo l'area del cerchio" return raggio ** 2 * pi def volume_cilindro(r, h): # esempio di docstring che serve a generare automaticamente la documentazione della funzione ''' Calcolo il volume di un cilindro. Parameters r : numero raggio del cilindro. h : numero altezza del cilindro. Returns volume del cilindro (float) ''' b = area_cerchio(r) return h*b def volume_del_cono(raggio, altezza): ''' Calcolo il volume del cono ''' return volume_cilindro(raggio, altezza)/3 print(volume_del_cono(27, 50)) # importo il modulo random per generare valori casuali import random def albero(tartaruga, tronco, livelli): ''' Disegna un albero con il modulo turtle Parameters tartaruga : istanza della classe turtle.Turtle tronco : numero lunghezza del tronco livelli : intero numero di livelli dell'albero da disegnare ''' if livelli==0: # se vogliamo disegnare un albero con 0 livelli di rami pass # non dobbiamo fare niente else: # altrimenti dobbiamo disegnare almeno un livello # disegno il tronco tartaruga.forward(tronco) # mi giro a sinistra di 30 gradi in modo da disegnare il ramo sinistro e tutto il sottoalbero di quella parte tartaruga.left(30) # disegno il sottoalbero (struttura di rami) sinistro con un livello di meno e con tronco leggermente più corto albero(tartaruga,tronco*0.8, livelli-1) # ruoto verso destra di 30+30 gradi in modo da dirigermi a 30° a destra del tronco tartaruga.right(60) # disegno il sottoalbero (struttura di rami) destro con un livello di meno e con tronco leggermente più corto del sx albero(tartaruga,tronco*0.7, livelli-1) # mi riallineo al tronco ruotando a sinistra di 30° tartaruga.left(30) # torno alla base del tronco ovvero alla posizione e direzione iniziale tartaruga.back(tronco) def albero_colorato(tartaruga, tronco, livelli): ''' Disegna un albero colorato a caso Parameters tartaruga : turtle.Turtle tartaruga che fa il disegno tronco : numero lunghezza del tronco livelli : intero numero di livelli delle impalcature di tronco/rami ''' if livelli>0: # cambio a caso il colore della penna tartaruga.color( random.randint(0,255), # luminosità della componente Red random.randint(0,255), # luminosità della componente Green random.randint(0,255), # luminosità della componente Blue ) tartaruga.pendown() # appoggio la penna sul foglio solo prima di disegnare il tronco tartaruga.forward(tronco) tartaruga.penup() # la sollevo tartaruga.left(30) albero_colorato(tartaruga,tronco*0.8, livelli-1) tartaruga.right(60) albero_colorato(tartaruga,tronco*0.7, livelli-1) tartaruga.left(30) tartaruga.back(tronco) def albero_e_lunghezza(tartaruga, tronco, livelli): ''' Disegna un albero colorato a caso e ne torna la lunghezza Parameters tartaruga : turtle.Turtle tronco : numero lunghezza del tronco livelli : intero numero di livelli dell'albero Returns int la lunghezza totale disegnata ''' if livelli>0: lunghezza = 0 # definisco e inizializzo la lunghezza totale tartaruga.color( random.randint(0,255), random.randint(0,255), random.randint(0,255), ) tartaruga.pendown() tartaruga.forward(tronco) tartaruga.penup() lunghezza += tronco # ci sommo la lunghezza de tronco appena disegnato tartaruga.left(30) # ottengo dalla chiamata ricorsiva la lunghezza del sottoalbero sinistro e la sommo lunghezza += albero_e_lunghezza(tartaruga,tronco*0.8, livelli-1) tartaruga.right(60) # ottengo dalla chiamata ricorsiva la lunghezza del sottoalbero destro e la sommo lunghezza += albero_e_lunghezza(tartaruga,tronco*0.7, livelli-1) tartaruga.left(30) tartaruga.back(tronco) return lunghezza # alla fine ritorno il valore della lunghezza totale else: # se non devo disegnare niente (caso base) return 0 # ritorno il valore 0 perchè non ho disegnato nulla def albero_parametrico(tartaruga, tronco, livelli, asx=30, adx=45, psx=0.8, pdx=0.7): ''' Disegna un albero e ne torna la lunghezza Parameters tartaruga : turtle.Turtle tartaruga che fa il disegno tronco : numero lunghezza del tronco livelli : intero numero di livelli dell'albero Opzionali: asx: int angolo di rotazione rispetto al tronco per disegnare il ramo/sottoalbero sinistro adx: int angolo di rotazione rispetto al tronco per disegnare il ramo/sottoalbero destro psx: float fattore di riduzione del ramo sinistro rispetto alla lunghezza del tronco psx: float fattore di riduzione del ramo destro rispetto alla lunghezza del tronco Returns int la lunghezza totale disegnata ''' if livelli>0: lunghezza = 0 tartaruga.color( random.randint(0,255), random.randint(0,255), random.randint(0,255), ) tartaruga.pendown() tartaruga.forward(tronco) tartaruga.penup() lunghezza += tronco tartaruga.left(asx) # uso gli argomenti per personalizzare la rotazione sinistra lunghezza += albero_parametrico(tartaruga,tronco*psx, livelli-1, asx, adx, psx, pdx) # accorcio di psx tartaruga.right(asx+adx) # la rotazione totale è la somma lunghezza += albero_parametrico(tartaruga,tronco*pdx, livelli-1, asx, adx, psx, pdx) # accorcio di pdx tartaruga.left(adx) # ruoto a destra tartaruga.back(tronco) return lunghezza else: return 0 ''' STRUTTURA DI UN PROBLEMA RICORSIVO - il problema è riducibile a sottoproblemi simili (un albero di N livelli è fatto da sottoalberi di N-1 livelli) - esiste almeno un problema elementare con soluzione conosciuta (caso base) (un albero di 0 livelli non disegna niente) - convergenza: a forza di ridurre il problema a sottoproblemi si arriva SEMPRE al caso base (a forza di ridurre di 1 il numero di livelli si arriva sempre a 0) (ma solo se N > 0) - la soluzione del problema più grande è ottenibile dalle soluzioni dei sottoproblemi (disegno il tronco e poi i due sottoalberi sinistro e destro) ''' # importo il modulo turtle per settarlo con i colori RGB a 255 valori import turtle #turtle.colormode(255) # faccio in modo che i colori siano definiti da terne di valori tra 0 e 255 if __name__ == '__main__': # vero se il file viene eseguito col comando "python lezione03.py" import turtle # importo la tartaruga t = turtle.Turtle() # ne creo una turtle.colormode(255) # setto il colormode per usare la notazione RGB con valori in 0..255 t.pensize(10) # ingrandisco il tratto del disegno t.speed(0) # massima velocità di disegno t.left(90) # verso l'alto lunghezza_totale = albero_parametrico(t, 100, 6, 20, 40, 0.6, 0.9) turtle.bye() # chiudo tutte finestre delle tartarughe print( "la lunghezza dell'albero è", lunghezza_totale)