Codice visto a lezione
Da aptiva.
trace.py
Ecco il codice deli decoratori tracer e memoizer:
def trace(f): def strtuple(x): return "("+str(x[0])+")" if len(x)==1 else str(x) def g(*x): print('| ' * trace.indent + '/-- ', f.__name__, strtuple(x), sep='') trace.indent += 1 value = f(*x) trace.indent -= 1 print('| ' * trace.indent + '\-- ', 'return', repr(value)) return value return g trace.indent=0 def memoize(f): cache = {} def g(*x): if x not in cache: cache[x] = f(*x) return cache[x] return g
Se chiamate il file "trace.py", ponendo "import trace" in testa ad un programma python: Se anteponete ad una funzione:
@trace.trace
verra' mostrata ogni chiamata della funzione e il valore ritornato. Se poi viene indicato:
@trace.memoize
verranno ricordati i valori gia' calcolati della funzione evitando di calcolare una seconda volta i valori già ottenuti.
matrici
Ecco gli esempi sulle matrici, il primo non usa la programmazione ad oggetti;
#!/usr/bin/env python3 import sys import random def random_matrix(nrows,ncols,maxvalue): return dict(((i,j),random.randint(0,maxvalue)) for i in range(nrows) for j in range(ncols)) def matrixdim(M): return max({i for i,_ in M.keys()})+1, max({j for _,j in M.keys()})+1 def print_matrix(msg, matrix): if matrix: nrows,ncols=matrixdim(matrix) print(msg, nrows, ncols) for i in range(nrows): for j in range(ncols): print("{:4d}".format(matrix[i,j]),end='') print() print() def matrixmul(A, B): Ar,Ac=matrixdim(A) Br,Bc=matrixdim(B) if Br != Ac: return None else: C={} for i in range(Ar): for j in range(Bc): C[i,j]=sum([A[i,k] * B[k,j] for k in range(Br)]) return C if __name__ == "__main__": print('Inserisci il numero di righe di A: ') a_row = int(input()) print('Inserisci il numero di colonne di A: ') a_column = int(input()) print('Inserisci il numero di righe di B: ') b_row = int(input()) print('Inserisci il numero di colonne di B: ') b_column = int(input()) A=random_matrix(a_row,a_column,10) B=random_matrix(b_row,b_column,10) print_matrix("A",A) print_matrix("B",B) C=matrixmul(A,B) print_matrix("C",C)
Il secondo e' ad oggetti e usa l'override degli operatori.
#!/usr/bin/env python3 import sys import random class matrix: def zero(): return 0 def __init__(self,nr,nc,initfun=zero): self.nr=nr self.nc=nc self.m=dict(((i,j),initfun()) for i in range(nr) for j in range(nc)) def dim(self): return self.nr, self.nc def __getitem__(self, key): return self.m[key] def __setitem__(self, key, value): self.m[key]=value def __add__(self, B): br,bc=B.dim() if br != self.nr or bc != self.nc: return None else: c=matrix(br,bc) for i in range(br): for j in range(bc): c[i,j] = self[i,j] + B[i,j] return c def __mul__(self, B): br,bc=B.dim() if self.nc != br: return None else: c=matrix(self.nr, bc) for i in range(self.nr): for j in range(bc): c[i,j] = sum([self[i,k] * B[k,j] for k in range(br)]) return c def __str__(self): s="{}x{}\n".format(self.nr,self.nc) fieldfmt="{{:{}}} ".format(max({len("{}".format(x)) for x in self.m})) for i in range(self.nr): for j in range(self.nc): s+=fieldfmt.format(self.m[i,j]) s+="\n" s+="\n" return s def rand10(): return random.randint(0,10) if __name__ == "__main__": print('Inserisci il numero di righe di A: ') a_row = int(input()) print('Inserisci il numero di colonne di A: ') a_column = int(input()) print('Inserisci il numero di righe di B: ') b_row = int(input()) print('Inserisci il numero di colonne di B: ') b_column = int(input()) A=matrix(a_row,a_column,rand10) B=matrix(b_row,b_column,rand10) print("A: ",A) print("B: ",B) print("A+B: ", A+B) print("A*B: ", A*B)