'''
ARGOMENTI:
---------------------------------------------------------------------

	overloading degli operatori
		Operazione di ridefinizione del  comportamento di un operatore applicato 
		ad un'istanza di una classe che abbiamo creato in precedenza.
		
		__add__		ridefinisce l'operatore + (addizione)
		__sub__		ridefinisce l'operatore - (sottrazione)
		__mul__		ridefinisce l'operatore * (moltiplicazione
		.......
		.......
		etc. etc. 
		
		Per il resto, fare riferimento alla guida di Python. 
		
		
	introspezione 
		Capacita' del codice di valutare altro codice o oggetti per determinare 
		gli attributi su "quello che sono" e "quello che fanno". 
		In Python la funzionalita' introspettiva e' integrata nel linguaggio, 
		In sostanza:
			- il codice puo' "auto-valutare" in fase di esecuzione
			- il programmatore puo' "manipolare" i risultati in base a variabili e attributi.
	
		
		
'''


class Matrice2x2:
	def __init__(self, a11, a12, a21, a22):
		self.a11 = a11
		self.a12 = a12
		self.a21 = a21
		self.a22 = a22
	
	def determinante(self):
		 return self.a11*self.a22-self.a21*self.a12 

	
	def visualizza(self):
		print ("|\t",self.a11,"\t", self.a12, "\t|")
		print ("|\t",self.a21,"\t", self.a22, "\t|")
		# "metodo determinante" invocato all'interno della classe 
		print("\n >>> Determinante:", self.determinante())
		print ("\n")
		
	
	def __add__(self, mat):
		add11=self.a11+mat.a11
		add12=self.a12+mat.a12
		add21=self.a21+mat.a21
		add22=self.a22+mat.a22
		return Matrice2x2(add11, add12, add21, add22)
		
	def __sub__(self, mat):
		sub11=self.a11-mat.a11
		sub12=self.a12-mat.a12
		sub21=self.a21-mat.a21
		sub22=self.a22-mat.a22
		return Matrice2x2(sub11, sub12, sub21, sub22)
	
	# introspezione	
	def __mul__(self, secArg):
		if type(secArg) is int:
			# prodotto per uno scalare
			mul11=self.a11*secArg 
			mul12=self.a12*secArg 
			mul21=self.a21*secArg 
			mul22=self.a22*secArg 
		else:
			# prodotto tra matrici
			mul11=self.a11*secArg.a11 + self.a12*secArg.a21 
			mul12=self.a11*secArg.a12 + self.a12*secArg.a22 
			mul21=self.a21*secArg.a11 + self.a22*secArg.a21 
			mul22=self.a21*secArg.a12 + self.a22*secArg.a22 
		
		
		return Matrice2x2(mul11, mul12, mul21, mul22)



print ("----------------------------------- ADDIZIONE ")
print ("Matrice A ")
matA=Matrice2x2(5,-3,0,1,)
matA.visualizza()
print ("Matrice B ")
matB=Matrice2x2(-2,1,5,-4,)
matB.visualizza()
print ("Matrice SOMMA ")
matSomma = matA+matB
matSomma.visualizza()
print ("---------------------------------- SOTTRAZIONE ")
print ("Matrice A ")
matA.visualizza()
print ("Matrice B ")
matB.visualizza()
print ("Matrice DIFFERENZA ")
matDiff = matA-matB
matDiff.visualizza()

print ("---------------------------------- MOLTIPLICAZIONE ")
print ("Matrice A ")
matA.visualizza()
print ("Matrice B ")
matB.visualizza()
print ("Matrice PRODOTTO ")
matPro = matA*matB
matPro.visualizza()

print ("---------------------MOLTIPLICAZIONE PER UNO SCALARE ")
print ("Matrice A ")
matA.visualizza()
print ("Matrice PRODOTTO - Scalare=3 ")
matPro = matA*3
matPro.visualizza()


