Diferència entre revisions de la pàgina «POO Operadors»

De Cacauet Wiki
Salta a la navegació Salta a la cerca
 
(Hi ha 4 revisions intermèdies del mateix usuari que no es mostren)
Línia 8: Línia 8:
  
 
Els més utilitzats son els operadors de comparació. Amb aquests podem definir comportaments dels objectes que definim a l'hora, per exemple, de fer ordenacions (sort) de llistes d'objectes.
 
Els més utilitzats son els operadors de comparació. Amb aquests podem definir comportaments dels objectes que definim a l'hora, per exemple, de fer ordenacions (sort) de llistes d'objectes.
 +
 +
Teniu altres exemples d'utilització d'operadors en [[POO operadors 2]].
 +
 +
<br>
  
 
== Exemple amb classes Python ==
 
== Exemple amb classes Python ==
Línia 50: Línia 54:
 
* No igualtat (!=): '''__ne__''' (not equal)
 
* No igualtat (!=): '''__ne__''' (not equal)
  
La distància a l'origen es defineix per sqrt(posx*posy) . Però a efectes de comparació en tenim prou en comparar posx*posy dels dos elements.
+
La distància a l'origen es defineix per:
 +
sqrt(posx<sup>2</sup>+posy<sup>2</sup>)
 +
Però a efectes de comparació en tenim prou en comparar els quadrats (si a>b, també es compleix a<sup>2</sup>>b<sup>2</sup>). Per tant, podem comparar:
 +
posx<sup>2</sup>+posy<sup>2</sup>
  
 
Definim els operadors bàsics: >, < i ==
 
Definim els operadors bàsics: >, < i ==
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
   def __gt__(self, other):
 
   def __gt__(self, other):
  return self.posx*self.posy > other.posx*other.posy
+
  return self.posx**2+self.posy**2 > other.posx**2+other.posy**2
 
   def __lt__(self, other):
 
   def __lt__(self, other):
  return self.posx*self.posy < other.posx*other.posy
+
  return self.posx**2+self.posy**2 < other.posx**2+other.posy**2
 
   def __eq__(self, other):
 
   def __eq__(self, other):
  return self.posx*self.posy == other.posx*other.posy
+
  return self.posx**2+self.posy**2 == other.posx**2+other.posy**2
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Línia 124: Línia 131:
 
   def __eq__(self, other):
 
   def __eq__(self, other):
 
       if type(other)==Pilota:
 
       if type(other)==Pilota:
         return self.posx*self.posy == other.posx*other.posy
+
         return self.posx**2+self.posy**2 == other.posx**2+other.posy**2
 
       elif type(other)==int:
 
       elif type(other)==int:
         return other == sqrt(self.posx*self.posy)
+
         return other == sqrt(self.posx**2+self.posy**2)
 
</syntaxhighlight>
 
</syntaxhighlight>

Revisió de 22:04, 31 oct 2013

Els operadors ens permeten operacions matemàtiques i lògiques. Els més coneguts serien:

  • Aritmètics: + , - , * , /
  • Lògics: and , or , not , xor
  • Comparacions: > , >= , < , <= , == , !=
  • Matemàtics: mod o % (resta divisió entera) , ...

Podeu llegir una referència més detallada del model de dades de Python.

Els més utilitzats son els operadors de comparació. Amb aquests podem definir comportaments dels objectes que definim a l'hora, per exemple, de fer ordenacions (sort) de llistes d'objectes.

Teniu altres exemples d'utilització d'operadors en POO operadors 2.


Exemple amb classes Python[modifica]

Per exemple, prenem el cas de la classe "Pilota".

class Pilota(object):
   # atributs
   velocitat = 10
   posx = 10
   posy = 12
   # mètodes
   def __init__(self, x=10, y=12):
      self.posx = x
      self.posy = y
   def accelera(self):
      self.velocitat = self.velocitat + 5
   def posicio(self,x,y):
      self.posx = x
      self.posy = y

Si intentem comparar 2 instàncies sense definir res, ho farà en virtut de la seva adreça de memòria, cosa que en principi no ens resulta útil per a res:

>>> a = Pilota()
>>> b = Pilota()
>>> id(a)
3073101612L
>>> id(b)
3073101580L
>>> a > b
True

Redefinint operadors[modifica]

Redefinirem els operadors: > , < i == . Utilitzarem el criteri de distància a l'origen (podria ser un altre criteri, com el tamany).

Es poden definir les següents funcions:

  • Major que (>): __gt__ (greater than)
  • Major igual (>=): __ge__ (greater equal)
  • Menor que (<): __lt__ (less than)
  • Menor igual (<=): __le__ (less equal)
  • Igualtat (==): __eq__ (equal)
  • No igualtat (!=): __ne__ (not equal)

La distància a l'origen es defineix per:

sqrt(posx2+posy2)

Però a efectes de comparació en tenim prou en comparar els quadrats (si a>b, també es compleix a2>b2). Per tant, podem comparar:

posx2+posy2

Definim els operadors bàsics: >, < i ==

   def __gt__(self, other):
	   return self.posx**2+self.posy**2 > other.posx**2+other.posy**2
   def __lt__(self, other):
	   return self.posx**2+self.posy**2 < other.posx**2+other.posy**2
   def __eq__(self, other):
	   return self.posx**2+self.posy**2 == other.posx**2+other.posy**2

Com podeu veure, els operadors necessiten 2 paràmetres: self i other. Un és l'objecte mateix i l'altre el que se li compara. Per veure que funciona farem:

>>> a = Pilota()
>>> b = Pilota()
>>> a == b
True
>>> a > b
False
>>> 
>>> a.posx = 100
>>> a == b
False
>>> a > b
True

Ordenant llistes[modifica]

Mercès a aquests operadors, ara podem ordenar un array de Pilotes. Per poder-ho comprovar, podem canviar la representació d'una pilota (quan fem un "print" o mostrem l'array):

   def __repr__(self):
	   return "(%d,%d)"%(self.posx,self.posy)

Ara podem veure les coordenades més fàcilment:

>>> a = Pilota()
>>> a
(10,12)
>>> print a
(10,12)

Fem un array i l'ordenem:

>>> c = [ Pilota(10,10) , Pilota(100,100) , Pilota(50,10) , Pilota(1,1) ]
>>> c
[(10,10), (100,100), (50,10), (1,1)]
>>> sorted(c)
[(1,1), (10,10), (50,10), (100,100)]

També tenim el mètode .sort() però aquest modifica permanentment l'ordre de la llista.

NOTA: de fet, per poder ordenar una llista, només és necessari implementar un dels dos operadors: > o bé < . Les funcions de Python ja s'encarreguen d'utilitzar el mètode que hem implementat per la classe.


Comparant diferents tipus de dades[modifica]

Si comparem una Pilota amb un integer veurem que ens dona un error:

>>> a = 10
>>> b = Pilota()
>>> a==b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "operadors.py", line 24, in __eq__
    return self.posx*self.posy == other.posx*other.posy
AttributeError: 'int' object has no attribute 'posx'

Si ens fixem bé veurem que és perquè el nostre mètode de comparació accedeix a un atribut "posx" que un int no té.

Si volem comparar 2 tipus de dades diferents caldrà implementar la selecció de tipus dins de l'operador de comparació.

...TODO... algo així:

   def __eq__(self, other):
      if type(other)==Pilota:
         return self.posx**2+self.posy**2 == other.posx**2+other.posy**2
      elif type(other)==int:
         return other == sqrt(self.posx**2+self.posy**2)