Questo notebook è da intendersi come supporto alle slides usate in aule, di cui si richiamano alcuni punte. Le slides sono disponibili sul sito del corso.
ESERCIZIO: Si consideri un polinomio di ordine $n$:
$$p(x) = a_0 x^0 + a_1 x^1 + ... + a_n x^n = \sum_{i=0,..,n} a_i x^i$$Scrivere una funzione che data la lista dei coefficienti del polinomio $[a_0, a_1, ..., a_n]$ restituisca due funzioni che, dato un punto $x$, la prima funzione calcoli il valore del polinomio $p(x)$, la seconda funzione calcoli la derivata prima del polinomio:
$$p'(x) = q(x) = a_1 x^0 + 2 a_2 x^1 + ... + n a_n x^{n-1} = \sum_{i=1,..,n} a_i x^{i-1}$$
In [ ]:
def MakePolyAndDerivate(As):
def Poly(x):
return sum(a*x**n for n,a in enumerate(As))
def PolyDerivate(x):
return sum((n+1)*a*x**n for n,a in enumerate(As[1:]))
return Poly, PolyDerivate
p,q = MakePolyAndDerivate([1, 0, 24])
print(p(0), q(0))
print(p(1), q(1))
In [ ]:
# Fattoriale
def Fattoriale(n):
if n == 0:
return 1
else:
return n*Fattoriale(n-1)
print(Fattoriale(4))
In [ ]:
# Fibonacci
def Fib(n):
if n == 0 or n == 1:
return 1
else:
return Fib(n-1) + Fib(n-2)
print(Fib(6))
In [ ]:
# Test if a list (e.g. string) is a palindrome
def IsPalindrome(Ls):
if len(Ls) <= 1:
return True
else:
return (Ls[0] == Ls[-1]) and IsPalindrome(Ls[1:-1])
print(IsPalindrome("abcdedcba"))
print(IsPalindrome("abcdeecba"))
Esempi da fare:
Fold:
$$\mbox{fold}(f,v_0,[v_1,v_2,v_3,...,v_n]) = f(v_1, f(v_2, f(v_3, ... f(v_n,v_0))))$$
In [ ]:
def Sum(Ls):
if Ls == []:
return 0
else:
return Ls[0] + Sum(Ls[1:]) # Notazione postfix per l'addizione
# Meglio se si usa operator.add dalla libreria operator
# https://docs.python.org/3.6/library/operator.html
def Add(x,y):
return x+y
def Sum2(Ls):
if Ls == []:
return 0
else:
return Add(Ls[0], Sum(Ls[1:])) # Notazione prefix per l'addizione
In [ ]:
def Mul(x,y):
return x*y
def Prod(Ls):
if Ls == []:
return 1
else:
return Mul(Ls[0], Prod(Ls[1:]))
In [ ]:
def Fold(F, v, Ls):
if Ls == []:
return v
else:
return F(Ls[0], Fold(F, v, Ls[1:]))
def FoldSum(Ls):
return Fold(Add, 0, Ls)
def FoldProd(Ls):
return Fold(Mul, 1, Ls)
foldCon la funzione fold appena vista, si possono scrivere diverse funzioni classiche che operano su delle liste. Si chiede di sviluppare come esercizio, le seguenti funzioni in termini di fold:
And(Ls): viene valutata a True se tutti gli elementi della lista sono TrueOr(Ls): viene valutata a True se almeno uno degli elementi della lista è TrueLength(Ls): determina la lughezza di una listaReverse(Ls): inverte il contenuto di una lista (esempio: [1,2,3,4] diventa [4,3,2,1])FoldFactorial(n): una funzione che calcola il fattoriale di nSumLength(Ls): restituisce una coppia di valori, data dalla somma degli elementi nella lista, e la lunghezza della stringa (esempio: SumLength([1,2,3,4]) = (10,4))Map(F, Ls): una funzione map equivalente alla builtin di pythonFilter(P, Ls): una funzione filter equivalente alla builtin di python
In [ ]:
# DA SCRIVERE LE 8 FUNZIONI RICHIESTE SOPRA
La funzione fold scritta sopra, viene generalmente chiamata foldRight in quando applica la funzione data agli elementi della lista utilizzando la convenzione che la funzione data sia associativa a destra. Per esempio, la funzione FoldSum come implementa sopra, se applicata alla lista $[1,2,3,4,5]$, calcola $(1+(2+(3+(4+(5+0)))))$.
ESERCIZIO: Si scriva una funzione fold che assuma che per la regola data valga regola associativa a sinistra, ovvero che data la lista $[1,2,3,4,5]$, calcoli $(((((0+1)+2)+3)+4)+5)$.
In [ ]:
def FoldLeft(F, v, Ls):
# DA COMPLETARE
pass
ESERCIZIO: Si scriva la funzione reverse(Ls) utilizzando la FolfLeft invece della Fold (se non altrimenti specificato, per fold si intende la FolfRight).
In [ ]:
def ReverseFoldL(Ls):
# DA COMPLETARE
pass
TODO: Commenti sulle differenze tra FoldRight e FoldLeft.