Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
(POO) en Python
ndice
Clases y objetos
Clases y atributos
Datos
Mtodos
Constructor
Objetos encrustados
Tema 2
POO en Python
x,y=1,0
Cmo representamos muchos puntos?
, , , = , , ,
xy= [[ , ],[ , ]]
Creamos un nuevo tipo: Punto
# Fichero Point.py:
class Point:
represents a point in 2-D space
.
Cmo comprobamos si entre dos puntos cul es el que est ms lejos del centro de
coordenadas?
POO en Python
Los objetos estn referenciados por variables de tipo igual al nombre de la classe.
Tema 2
POO en Python
Clases y objetos:
La varia le a contiene
referencia que apunta a:
Objeto de tipo Point e.d.
instancia de la clase Point en
direccin 0x0F45
La varia le contiene
referencia que apunta a:
Definicin de la clase:
b=Point()
class Point:
#cdigo...
La varia le contiene
referencia que apunta a:
Objeto de tipo Point e.d.
instancia de la clase Point en
direccin 0xFF25
Tema 2
POO en Python
ndice
Clases y objetos
Clases y atributos
Datos
Mtodos
Constructor
Objetos encrustados
Tema 2
POO en Python
Df. Diagrama del objeto diagrama del estado que indica los
valores de los atributos del objeto:
Tema 2
POO en Python
10
>>>blank=Point()
>>>print blank.y
4.0
>>> x = blank.x
>>> print x
3.0
>>> print ( + str(blank.x) + , + str(blank.y) + )
>>> distanceSquared = blank.x * blank.x + blank.y * blank.y
Tema 2
POO en Python
11
ndice
Clases y objetos
Clases y atributos
Datos
Mtodos
Constructor
Objetos incrustados
POO en Python
12
class Time(object):
"""represents the time of day.
attributes: hour, minute, second""
>>>time = Time()
>>>time.hour = 11
>>>time.minute = 59
>>>time.second = 30
Tema 2
POO en Python
13
>>> print_time(start)
09:45:00
Tema 2 POO
en Python
Petia
Ivanova
Radeva
Ha de ser una funcin
global?
Cmo definir una funcin de
una
clase?
14
class Time(object):
def print_time(self): #mtodo de la clase
print '%.2d:%.2d:%.2d % (self.hour, self.minute, self.second)
Tema 2
POO en Python
15
>>> start=Time()
>>>start.hour=9
>>>start.minute=45
>>>start.second=00
>>> print start.hour # imprimimos el dato hour de
9
>>>start.print_time() #llamamos el mtodo de la clase con el objeto (start)
09:45:00
>>>start2=Time()
.
POO en Python
16
POO en Python
17
POO en Python
18
return sum
POO en Python
19
POO en Python
20
La forma correcta para modificar a los valores de las clases es a travs de los mtodos setValor().
POO en Python
21
Tema 2
POO en Python
22
Clases y atributos
Df. Un mtodo es una funcin asociada con una clase (p.e. concatenacin de
cadenas).
Tema 2
POO en Python
23
class Time(object):
def __init__(self, hour=0, minute=0, second=0):
#coincidencia de los nombres
self.hour = hour
# define los atributos de la
clase
self.minute = minute
self.second = second
>>>t1=Time(1,2,3)
POO en Python
24
Constructor: __init__
POO en Python
26
Self
Recordar:
Aunque se debe especificar self de forma explcita en la
definicin del mtodo, no es necesario incluirla en la llamada
al mtodo.
Python lo pasa de forma automtica.
Llamada al mtodo:
>>> x.setMinute(23)
POO en Python
29
NO!!!
class Time(object):
def __init__(self, hour=0,
minute=0, second=0):
#coincidencia de los
nombres
self.hour = hour
self.minute = minute
self.second = second
def time_to_int(self).
>>>t1=Time(1,2,3)
Tema 2
POO en Python
30
POO en Python
# se llama el constructor
# con los valores por
# no se aplican
31
# Access an attribute.
# Access a method.
getattr(object_instance, string)
>>> f = student(Bob Smith, 23)
>>> getattr(f, full_name)
Bob Smith
>>> getattr(f, get_age)
<method get_age of class studentClass at 010B3C2>
>>> getattr(f, get_age)()
23
hasattr(object_instance,string)
>>> f = student(Bob Smith, 23)
>>> hasattr(f, full_name)
True
>>> hasattr(f, get_age)
True
>>> hasattr(f, get_birthday)
False
Atributos
Atributos de datos
class teacher:
A class representing teachers.
def __init__(self,n):
self.full_name = n
def print_name(self):
print self.full_name
Petia Ivanova Radeva
Atributos de la clase
class sample:
x = 23
def increment(self):
self.__class__.x += 1
>>> a = sample()
>>> a.increment()
>>> a.__class__.x
24
Petia Ivanova Radeva
>>>
>>>
>>>
>>>
>>>
>>>
1
>>>
a = counter()
b = counter()
a.increment()
b.increment()
b.increment()
a.my_total
a.__class__.overall_total
3
>>> b.my_total
2
>>> b.__class__.overall_total
3
ndice
Clases y objetos
Clases y atributos
Datos
Mtodos
Constructor
Objetos encrustados
POO en Python
43
Objetos encrustados
POO en Python
44
Objetos incrustados:
Instancias de objetos como valores de retorno
# En la clase Rectangle:
def find_center(self):
return Point(self.corner.x + self.width/2.0,
self.corner.y +
self.height/2.0)
>>> mibox = Rectangle(100,200,0,0)
>>> center=mibox.find_center()
>>> print center
(50.0, 100.0)
Qu sucede con el objeto que retorna la funcin find_center()?
>>>a=[]
>>>a.append(Point(10,4))
Tema 2
POO en Python
45
ndice
Clases y objetos
Clases y atributos
Datos
Mtodos
Constructor
Objetos encrustados
POO en Python
46
Tema 2
POO en Python
47
Tema 2
POO en Python
>>> mibox2 =
copy.copy(mibox)
>>> print mibox2 is mibox
False
>>> print mibox2==mibox
False
Petia Ivanova Radeva
48
POO en Python
49
Tema 2
POO en Python
50
Conclusiones
Los constructores son mtodos de las clases que tienen el objetivo de crear los objetos e
inicializar sus valores.
Se ha de evitar inicializar los datos de la clase fuera de los constructores.
La forma correcta para acceder a los valores de las clases es a travs de funciones getValor()
y setValor().
Por defecto, intentar definir los mtodos como mtodos puros.
POO en Python
51
ndice
Tipos de atributos
Objetos incrustados
Encapsulamiento
Polimorfismo y sobrecarga
Herencia
Tema 2
POO en Python
Bob Smith
>>> lista=[]
>>> lista.append(Student( Bob Smith , 23))
>>> lista.append(Student(Anna Kournikova, 25))
getattr(object_instance, string)
>>> f = Student( Bob Smith , 23)
>>> getattr(f,
Bob Smith
full_name )
get_age )()
hasattr(object_instance,string)
>>> f = Student( Bob Smith , 23)
>>> hasattr(f,
True
full_name )
>>> hasattr(f,
True
get_age )
>>> hasattr(f,
False
get_birthday )
ndice
Tipos de atributos
Objetos incrustados
Encapsulamiento
Polimorfismo y sobrecarga
Herencia
Tema 2
POO en Python
Atributos de datos
class Teacher:
A class representing teachers.
def __init__(self,n):
self.full_name = n
def print_name(self):
print self.full_name
Petia Ivanova Radeva
Atributos de la clase
class Sample:
x = 23
def increment(self):
self.__class__.x += 1
Sample.x+=1
>>> a = Sample()
>>> a.increment()
>>> print a.__class__.x
24
>>> print Sample.x
24
Petia Ivanova Radeva
>>> a = Counter()
>>> b = Counter()
>>> Counter.overall_total
0
>>>
>>>
>>>
>>>
1
>>>
a.increment()
b.increment()
b.increment()
a.my_total
a.__class__.overall_total
3
>>> b.my_total
2
>>> b.__class__.overall_total
3
ndice
Tipos de atributos
Objetos incrustados
Encapsulamiento
Polimorfismo y sobrecarga
Herencia
Tema 2
POO en Python
13
Objetos incrustados
class Rectangle:
"""represents a rectangle. attr: width, height, corner"
def __init__(self, width, height, cornerx, cornery):
self.width, self.height=width, height
self.corner=Point(cornerx,cornery)
POO en Python
14
Objetos incrustados:
Instancias de objetos como valores de retorno
# En la clase Rectangle:
def find_center(self):
return Point(self.corner.x + self.width/2.0,
self.corner.y + self.height/2.0)
POO en Python
15
Objetos incrustados:
Instancias de objetos como valores de retorno
# En la clase Rectangle:
def find_center(self):
return Point(self.corner.x + self.width/2.0,
self.corner.y + self.height/2.0)
>>>a=[]
>>>a.append(Point(10,4))
>>>a.append(center)
Tema 2
POO en Python
16
ndice
Tipos de atributos
Objetos incrustados
Encapsulamiento
Polimorfismo y sobrecarga
Herencia
Tema 2
POO en Python
17
POO en Python
18
Tema 2
POO en Python
19
POO en Python
20
Tema 2
POO en Python
21
Tema 2
POO en Python
22
ndice
Tipos de atributos
Objetos incrustados
Encapsulamiento
Polimorfismo y sobrecarga
Herencia
Tema 2
POO en Python
23
.
Construimos el objeto:
>>>myfraction=Fraction(3,5)
>>>print myfraction.den
# llamamos un dato de la clase
No recomendable! La forma correcta ser:
>>>myfraction.imprimir()
# llamamos un mtodo de la clase
Y o pode os p ohi i el a eso a los at i utos?
Tema 2
POO en Python
24
Tema 2
POO en Python
25
POO en Python
26
POO en Python
27
Encapsulamiento
Tema 2
POO en Python
28
Encapsulamiento
Hay muchos datos que no tiene porque conocerlo aquel que est
usando la clase; ya que son inherentes al objeto y slo controlan
su funcionamiento interno
POO en Python
29
Encapsulamiento
POO en Python
30
Encapsulamiento
El encapsulamiento es muy conveniente y nos permite colocar nuestro objeto
en funcionamiento en cualquier tipo de sistema, de una manera modular y
escalable (algunas de las reglas de la ingenieria del software).
Tema 2
POO en Python
31
Encapsulamiento
Porcin visible: interfaz (protocolo)
Contrato pblico de comportamiento.
Tema 2
POO en Python
32
ndice
Tipos de atributos
Objetos incrustados
Encapsulamiento
Polimorfismo y sobrecarga
Herencia
Tema 2
POO en Python
33
Implementacin del
comportamiento de la clase
>>myf=Fraction(3,5)
>>print myf # print espera una cadena para imprimir
<__main__.Fraction instance at 0x409b1acc>
Solucin a):
class Fraction:
.
def show(self):
print self.__num,"/",
self.__den
Tema 2
POO en Python
>>myf=Fraction(3,5)
>>print myf
<__main__.Fraction
instance at
0x409b1acc>
>>myf.show()
3/5
34
POO en Python
35
Tema 2
POO en Python
36
Polimorfismo
Tema 2
POO en Python
37
Polimorfismo y sobrecarga
Tema 2
POO en Python
38
Sobrecarga de mtodos
>>f1=Fraction(1,4)
>>f2=Fraction(1,2)
>>f1+f2
def __add__(self,otherfraction):
newnum = self.__num*otherfraction.__den + \
self.__den*otherfraction.__num
newden = self.__den * otherfraction.__den
return Fraction(newnum,newden)
>>f3=f1+f2 # equivalente a: f3=f1.__add__(f2)
>>print f3
6/8
Tema 2
POO en Python
39
is o
Tema 2
POO en Python
40
POO en Python
41
def __add__(self,otherfraction):
newnum =self.__num*otherfraction.__den + \
self.__den*otherfraction.__num
newden = self.__den*otherfraction.__den
com = gcd(newnum,newden)
return Fraction(newnum/com,newden/com)
def __cmp__(self,otherfraction):
num1 = self.__num*otherfraction.__den
num2 = self.__den*otherfraction.__num
if num1 < num2:
return -1
else:
if num1 == num2:
return 0
else: return 1
POO en Python
42
Sobrecarga de operadores
POO en Python
43
Qu operadores sobrecargar?
Mtodos especiales
class Student:
...
def __repr__(self):
return Im named
+ self.__full_name
# Note: we changed the full_name to __full_name
Mtodos especiales
Podemos sobrecargar:
__init__ : El constructor de la clase.
__cmp__ : Define como aplicar == para la clase.
__len__ : Define len( obj ).
__copy__ : Define cmo copiar un objeto de la clase.
__getitem__ : Define el operador [].
__doc__ : Variable que guarda la documentacin de la clase.
>>> f = Student( Bob Smith , 23)
>>> print f.__doc__
A class representing a student.
Consultar qu otros mtodos se pueden sobrecargar!
Petia Ivanova Radeva
POO en Python
47
ndice
Tipos de atributos
Objetos incrustados
Encapsulamiento
Polimorfismo y sobrecarga
Herencia
Tema 2
POO en Python
48
Subclases
Ejercicio
class Main:
def __init__(self,p):
self._pp=p
def f(self):
print self._pp
def getpp(self):
return self._pp
Tema 2
POO en Python
Derivative
Main
_pp
f()
getpp()
__qq
f2()
getqq()
>>>o1=Main(3)
>>>o2=Derivative(5,4)
>>>print
o2.getpp(),o2.getqq()
>>>o2.f()
>>>o2.f2()
Petia Ivanova Radeva
50
Cuando creamos una clase derivada a partir de una clase base y tenemos que la
clase derivada proporciona o requiere su propio mtodo __init__, este mtodo de
la clase derivada debe llamar explcitamente el mtodo __init__ de la clase base
Propiedades de la herencia
POO en Python
54
Herencia
Adems, las clases derivadas pueden ser base de otras clases derivadas.
Se pueden montar jerarquas de clases.
POO en Python
55
class Guitarra(Instrumento):
#Clase Derivada
pass
class Bajo(Instrumento):
#Clase Derivada
pass
Tema 2
POO en Python
56
Ejemplo
class Instrumento:
def __init__(self, precio):
self.__precio = precio
def tocar (self):
print "Estamos tocando musica
def romper (self):
print "Esto lo pagas tu"
print "Son,self.__precio,
euros
class Guitarra (Instrumento):
def __init__ (self, cuerdas, precio):
Instrumento.__init__(self,
precio)
self.__cuerdas = cuerdas
def tocar(self):
print "Estamos tocando la
guitarra de ", self.__cuerdas,
" cuerdas"
Tema 2
POO en Python
def main():
instru = Instrumento(20)
guitar = Guitarra(5, 100)
instru.romper()
guitar.romper()
instru.tocar()
guitar.tocar()
main()
57
POO en Python
def main():
instru = Instrumento(20)
guitar = Guitarra(5, 100)
instru.romper()
guitar.romper()
instru.tocar()
guitar.tocar()
main()
58
Conclusiones
La forma correcta para acceder a los valores de las clases es a travs de funciones getValor() y setValor().
Una solucin es copiar los objetos usando la copia simple o la copia profunda.
La encapsulacin de los datos y los mtodos es un proceso de organizarlos en clases donde se separa la
interfaz de la clase de la implementacin de sus mtodos
El polimorfismo es la capacidad de definir operaciones bsicas de los tipos (mtodos de las clases) que
tiene el mismo objetivo aunque puedan tener diferente implementacin.
Las clases se pueden organizar en jerarquas. Las jerarquias permiten realizar herencia de mtodos y
datos de las clases bases por las clases derivadas
Es una forma muy eficiente de reaprovechar el cdigo, escribir de forma compacta y concisa y minimizar los errores.
Tema 2
POO en Python
59
Material adicional
Tema 2
POO en Python
60
pades
Hea ts
Dia o ds
Clu s 0
Jack 7 11
Queen 7 12
King 7 13
class Card:
POO en Python
61
Atributos de la clase
# inside class Card:
_suit_names = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
_rank_names = [None, 'Ace', '2', '3', '4', '5', '6', ' ,' ', '9', '10', 'Jack', 'Queen', 'King']
def __str__(self):
return '%s of %s' % (Card._rank_names[self._rank],
Card._suit_names[self._suit])
>>> card1 = Card(2, 11)
>>> print card1
Jack of Hearts
Tema 2
POO en Python
62
Tema 2
POO en Python
63
El juego de cartas
# inside class Card:
# implementacin compacta
def __cmp__(self, other):
t1 = self._suit, self._rank
t2 = other.getSuit(), other.getRank()
return cmp(t1, t2)
Utilizamos la definicin preimplementada del operador cmp!
Tema 2
POO en Python
64
Baraja
class Deck(object):
def __init__(self):
self._cards = []
for suit in range(4):
for rank in range(1, 14):
card = Card(suit, rank)
self._cards.append(card)
Tema 2
POO en Python
65
Imprimiendo la baraja
#inside class Deck:
def __str__(self):
res = []
for card in self._cards:
res.append(str(card))
return '\n'.join(res)
Tema 2
POO en Python
66
Tema 2
POO en Python
67
POO en Python
68
',\
def __str__(self):
return '%s of %s' %\
(self._rank_names[self._rank], self._suit_names[self._suit])
def __cmp__(self, other):
t1 = self._suit, self._rank
t2 = other.getSuit(), other.getRank()
return cmp(t1, t2)
Petia Ivanova Radeva
class Hand(object):
def __init__(self, label=''):
self._cards = []
self._label = label
def __str__(self):
res = []
for card in self._cards:
res.append(str(card))
return '\n'.join(res)
def pop_card(self):
return self._cards.pop()
class Hand(Deck):
def __init__(self, label=''):
self._cards = []
self._label = label
IS-A
HAS-A
...
>>>h=Hand()
>>> deck = Deck()
>>> c1=Card()
>>> card1 = Card(2, 11)
>>> print card1
Jack of Hearts
>>> hand = Hand('new hand')
>>> print hand.cards
[]
>>> print hand.label
new hand
>>> deck = Deck()
Los otros mtodos se heredan de la
clase Deck as que podemos utilizar
pop_card y add_card:
>>> card = deck.pop_card()
>>> hand.add_card(card)
>>> print hand
King of Spades
Petia Ivanova Radeva
Jugar
En qu clase pondras el siguiente
mtodo?
def move_cards(self, hand, num):
for i in range(num):
hand.add_card(self.pop_card())
HAS-A
IS-A
Tema 2
POO en Python
73
El juego
Implementar un juego que:
Mezcla las cartas y las reparte entre 2 jugadores.
2. Se juega hasta que alguno de los jugadores se quede sin
cartas.
3. A cada iteracin, cada uno saca una carta.
1.
4.
Tema 2
POO en Python
74
El juego
# Crear la baraja y mezclar las cartas
deck=Deck()
deck.shuffle()
POO en Python
#jugar
while(hand1.len()>0 and hand2.len()>0):
card1=hand1.pop_card()
card2=hand2.pop_card()
if card1<card2:
hand1.add_card(card1)
hand1.add_card(card2)
else:
hand2.add_card(card1)
hand2.add_card(card2)
print hand1.len()
print hand2.len()
print
#determinar el ganador
if (hand1.len()>0):
print "The winner is: Hand1"
else: print "The winner is: Hand2"
Petia Ivanova Radeva
75
Ejemplo
>>> die1 = MSDie(6)
#definimos un dado de 6 puntos
>>> die1.getValue()
1
>>> die1.roll()
>>> die1.getValue()
4
>>> die2 = MSDie(13)
#definimos un dado de 13 puntos
>>> die2.getValue()
1
>>> die2.roll()
>>> die2.getValue()
12
>>> die2.setValue(8)
>>> die2.getValue()
8
Petia Ivanova Radeva
Puntos
Rectngulos (dados, botones)
.
Cuadrados, rombos, romboides
Polgonos
Crculos
Formas ovales
Lineas
Textos
Imgenes
Tema 2
POO en Python
80
Bounding
Box
Imagen
Punto
Forma
Oval
Lnea
Rectngulo
Texto
Crculo
81
def undraw(self):
"""Undraw the object (i.e. hide it). Returns silently
if the object is not currently drawn."""
POO en Python
82
La clase Punto
class Point(GraphicsObject):
def __init__(self, x, y):
GraphicsObject.__init__(self, ["outline", "fill"])
self.setFill = self.setOutline
self.x = x
self.y = y
def _draw(self, canvas, options):
x,y = canvas.toScreen(self.x,self.y)
return \
canvas.create_rectangle(x,y,x+1,y+1,options)
Tema 2
POO en Python
83
La clase BoundingBox
class _BBox(GraphicsObject):
# Internal base class for objects represented by bounding box
# (opposite corners) Line segment is a degenerate case.
def __init__(self, p1, p2, options=["outline","width","fill"]):
def _move(self, dx, dy):
def getP1(self):
def getP2(self):
def getCenter(self):
Tema 2
POO en Python
84
La clase Rectngulo
class Rectangle(_BBox):
def __init__(self, p1, p2):
def _draw(self, canvas, options):
def clone(self):
Tema 2
POO en Python
85
Tema 2
POO en Python
86
La clase Crculo
class Circle(Oval):
def __init__(self, center, radius):
def clone(self):
def getRadius(self):
Tema 2
POO en Python
87
Constructor
myCircle = Circle(Point(0,0), 20) # se llama al constructor
class Circle(Oval):
def __init__(self, center, radius):
p1 = Point(center.x-radius, center.y-radius)
p2 = Point(center.x+radius, center.y+radius)
Oval.__init__(self, p1, p2)
self.radius = radius
La clase Lnea
class Line(_BBox):
def __init__(self, p1, p2):
def clone(self):
def _draw(self, canvas, options):
def setArrow(self, option):
Tema 2
POO en Python
89
La clase Polgono
class Polygon(GraphicsObject):
def __init__(self, *points):
# if points passed as a list, extract it
def clone(self):
def getPoints(self):
def _move(self, dx, dy):
def _draw(self, canvas, options):
Tema 2
POO en Python
90
La clase Imagen
class Image(GraphicsObject):
def __init__(self, p, pixmap):
def _draw(self, canvas, options):
def _move(self, dx, dy):
def undraw(self):
def getAnchor(self):
def clone(self):
Tema 2
POO en Python
91
La clase Texto
class Text(GraphicsObject):
def __init__(self, p, text):
def _draw(self, canvas, options):
def getText(self):
def getAnchor(self):
def setFace(self, face):
def clone(self):
def setText(self,text):
Tema 2
POO en Python
92
Uso
from graphics import *
win = GraphWin()
win.setCoords(0,0,10,10)
p=Point(3,4)
p.draw(win)
win = GraphWin()
win.setCoords(0,0,10,10)
t = Text(Point(5,5), "Centered Text")
t.draw(win)
p = Polygon(Point(1,1), Point(5,3), Point(2,7))
p.draw(win)
e = Entry(Point(5,6), 10)
e.draw(win)
win.getMouse()
p.setFill("red")
p.setOutline("blue")
p.setWidth(2)
s="
for pt in p.getPoints():
s = s + "(%0.1f,%0.1f) " % (pt.getX(), pt.getY())
Tema 2
POO en Python
93
Tema 2
POO en Python
t.setText(e.getText())
e.setFill("green")
e.setText("Spam!")
e.move(2,0)
win.getMouse()
p.move(2,3)
s = ""
for pt in p.getPoints():
s = s + "(%0.1f,%0.1f) " %\
(pt.getX(), pt.getY())
t.setText(s)
win.getMouse()
p.undraw()
e.undraw()
t.setStyle("bold")
win.getMouse()
t.setStyle("normal")
win.getMouse()
t.setStyle("italic")
win.getMouse()
t.setStyle("bold italic")
win.getMouse()
t.setSize(14)
win.getMouse()
t.setFace("arial")
t.setSize(20)
win.getMouse()
win.close()
94
Al ap eta el ot
la aplicacin
Tema 2
Quit se ie a
POO en Python
95
Usando widgets
La clase botn
Mtodos de la clase botn
constructor
activate
deactivate
clicked
getLabel
def activate(self):
"Sets this button to active."
self.label.setFill(black)
self.rect.setWidth(2)
self.active = 1
Petia Ivanova Radeva
La clase botn
def deactivate(self):
"ets this utto to i a tive."
self.la el.setFill da kg ey
self.rect.setWidth(1)
self.active = 0
La clase botn
pt = win.getMouse()
if button1.clicked(pt):
# Do button1 stuff
elif button2.clicked(pt):
# Do button2 stuff
elif button3.clicked(pt)
# Do button3 stuff
...
La clase botn
# Button.py
from graphics import *
class Button:
"""A button is a labeled rectangle in a window.
It is activated or deactivated with the activate()
and deactivate() methods. The clicked(p) method
returns true if the button is active and p is inside it."""
Constructor
setValue()
La clase DieView
class DieView:
""" DieView is a widget that displays a graphical
representation of a standard six-sided die.""
def __init__(self, win, center, size):
"""Create a view of a die, e.g.:
d1 = GDie(myWin, Point(40,50), 20)
creates a die centered at (40,50) having sides
of length 20."""
La funcin __makePip()
def __makePip(self, x, y):
"Internal helper method to draw a pip at (x,y)"
pip = Circle(Point(x,y), self.psize)
pip.setFill(self.background)
pip.setOutline(self.background)
pip.draw(self.win)
return pip
def setValue(self, value):
"Set this die to display value."
# turn all pips off
self.pip1.setFill(self.background)
self.pip2.setFill(self.background)
self.pip3.setFill(self.background)
self.pip4.setFill(self.background)
self.pip5.setFill(self.background)
self.pip6.setFill(self.background)
self.pip7.setFill(self.background)
# turn correct pips on
if value == 1:
self.pip4.setFill(self.foreground)
elif value == 2:
self.pip1.setFill(self.foreground)
self.pip7.setFill(self.foreground)
elif value == 3:
self.pip1.setFill(self.foreground)
self.pip7.setFill(self.foreground)
self.pip4.setFill(self.foreground)
elif value == 4:
self.pip1.setFill(self.foreground)
self.pip3.setFill(self.foreground)
self.pip5.setFill(self.foreground)
self.pip7.setFill(self.foreground)
elif value == 5:
self.pip1.setFill(self.foreground)
self.pip3.setFill(self.foreground)
self.pip4.setFill(self.foreground)
self.pip5.setFill(self.foreground)
self.pip7.setFill(self.foreground)
else:
self.pip1.setFill(self.foreground)
self.pip2.setFill(self.foreground)
self.pip3.setFill(self.foreground)
self.pip5.setFill(self.foreground)
self.pip6.setFill(self.foreground)
self.pip7.setFill(self.foreground)
Petia Ivanova Radeva
La aplicacin final
# roller.py
# Graphics program to roll a pair of dice. Uses custom
widgets Button and DieView.
from random import randrange
from graphics import GraphWin, Point, Rectangle
from button import Button
from dieview import DieView
def main():
# create the application window
win = GraphWin("Dice Roller")
win.setCoords(0, 0, 10, 10)
win.setBackground("green2")
# Draw the interface widgets
die1 = DieView(win, Point(3,7), 2)
die2 = DieView(win, Point(7,7), 2)
rollButton = Button(win, Point(5,4.5), 6, 1, "Roll
Dice")
rollButton.activate()
quitButton = Button(win, Point(5,1), 2, 1, "Quit")
# Event loop
pt = win.getMouse()
Tema 5
Tema 3
Pilas y Colas
Objetivos
Entender la lgica de las estructuras bsicas: pila, cola, cola de prioridad y deque.
Ser capaces de implementar los tipos de datos abstractos pila, cola, cola de
prioridad y deque.
Ser capaz de reconocer las propiedades de los problemas, donde son apropiadas
las pilas, colas, cola de prioridad y deques.
Tema 3
Pilas y Colas
Tema 3
Pilas y Colas
Pilas
Ejemplos
La pila de objetos en Python
El botn Back del web browser
El comando undo
Tema 3
Pilas y Colas
Pilas
La indexacin no es posible/eficiente.
Pero s cules han sido introducidos los ltimos.
Los elementos no estan fsicamente juntos -> apropiada para grandes volmenes de datos
La pila se expande automticamente.
Pilas y Colas
Datos secuencia lineal ordenada de elementos heterogneos que se aaden y borran del
mismo extremo.
Operaciones bsicas:
Stack() crea una pila vaca. No necesita parmetros y retorna una pila vaca.
push(item) aade un nuevo elemento al top de la pila. Necesita el elemento como parmetro y no
retorna nada.
pop() borra el elemento del top de la pila. No necesita parmetros y retorna el elemento borrado del
top.
peek() retorna el primer elemento de la pila sin borrarlo de la pila. La pila no se modifica.
isEmpty() comprueba si la pila est vaca. No necesita parmetros y retorna un valor booleano.
size() o __len__() retorna el nmero de elementos de la pila. No necesita parmetros y retorna un
entero.
Tema 3
Pilas y Colas
Contenido de la pila
Valor de retorno
s.isEmpty()
s.push(4)
s.push( dog )
s.peek()
s.push(True)
len(s)
s.isEmpty()
s.push(8.4)
s.pop()
s.pop()
len(s)
Tema 3
Pilas y Colas
Contenido de la pila
Valor de retorno
s.isEmpty()
[]
True
s.push(4)
[4]
s.push( dog )
[4, dog ]
s.peek()
[4, dog ]
s.push(True)
len(s)
s.isEmpty()
False
s.push(8.4)
s.pop()
8.4
s.pop()
[4, dog ]
True
len(s)
[4, dog ]
Tema 3
Pilas y Colas
dog
def __str__(self):
def isEmpty(self):
def push(self, item):
def pop(self):
def peek(self):
def __len__(self):
Tema 3
Pilas y Colas
Uso
Explicacion
append
milista.append(elemento)
insert
milista.insert(i, item)
pop
milista.pop()
pop
milista.pop(i)
sort
milista.sort()
reverse
milista.reverse()
Invierte la lista
del
del milista[i]
Borra el elemento i
index
milista.index(item)
count
milista.count(item)
remove
milista.remove(item)
Tema 1
Abstraccin de datos
10
Pilas y Colas
11
def
def
def
def
def
Pilas y Colas
12
Tema 3
Pilas y Colas
class Stack:
Define un TDA Pila
def __init__(self):
self.__items = []
def __str__(self):
return ''.join(str(elem)+', '
for elem in self.__items)
def isEmpty(self):
return self.__items == []
def push(self, item):
self.__items.insert(0,item)
def pop(self):
return self.__items.pop(0)
def peek(self):
if len(self)>0:
return self.__items[0]
else: return None
def __len__(self):
return len(self.__items)
13
Test
Las fu cio es
E la clase pila, el
Tema 3
Pilas y Colas
14
Fijmonos que cada parntesis que cierra corresponde al ltimo parntesis que
abre.
Tema 3
Pilas y Colas
15
Implementacin
def parChecker(symbolString):
s = Stack()
balanced, index = True, 0
while index < len(symbolString) and balanced:
symbol = symbolString[index]
if symbol == '(': s.push(symbol)
elif symbol==')':
if s.isEmpty(): balanced = False
else: s.pop()
index += 1
Pilas y Colas
16
({[]){})]
(({{[[]]}{[][]}}()))
[{( )}{}]
Tema 3
Pilas y Colas
17
Implementacin
def parCheckerComplete(symbolString):
s = Stack()
balanced,index = True,0
while index < len(symbolString) and balanced:
symbol = symbolString[index]
if symbol in '([{': s.push(symbol)
elif symbol in ')]}':
if s.isEmpty():
balanced = False
else:
Hay acceso a los
atributos privados de la
top = s.pop()
clase Stack?
if not matches(top,symbol):
balanced = False
index += 1
if balanced and s.isEmpty():
return True
else:
return False
Tema 3
Pilas y Colas
18
Implementacin
def matches(open,close):
opens = "([{"
closers = ")]}
return opens.index(open) == closers.index(close)
>>parChecker('()()()()(())()())
True
Tema 3
Pilas y Colas
19
Aplicaciones
Backtracking
Evaluacin de
expresiones y anlisis de
sintxis
Lenguajes de
programacin basados en
pilas
Tema 3
Pilas y Colas
20
Tema 3
Pilas y Colas
21
a. Datos
i. Cards
b. Mtodos
i. Constructor (__init__).
ii. show_last_card - retorna la ltima carta.
iii. append aadir una carta a la pila.
iv. len - Comprobar cuntas cartas tiene la pila.
v. test define funcin de test.
Pilas y Colas
22
Colas
Ejemplos:
La cola de impresin
El buffer de la secuencia de teclas
Tema 3
Pilas y Colas
23
Colas
- first-come first-served.
Pilas y Colas
24
Colas
Pilas y Colas
25
Tema 3
Pilas y Colas
26
Cola
Operacin
Contenido de la cola
Valor de retorno
q.isEmpty()
q.enqueue(4)
q.enqueue( dog )
q.enqueue(True)
len(q)
q.isEmpty()
q.enqueue(8.4)
q.dequeue()
q.dequeue()
len(q)
Tema 3
Pilas y Colas
27
Cola
Operacin
Contenido de la cola
Valor de retorno
q.isEmpty()
[]
True
q.enqueue(4)
[4]
q.enqueue( dog )
[ dog ,4]
q.enqueue(True)
len(q)
q.isEmpty()
False
q.enqueue(8.4)
q.dequeue()
[8.4,True, dog ]
q.dequeue()
[8.4,True]
dog
len(q)
[8.4,True]
Tema 3
Pilas y Colas
28
Tema 3
Pilas y Colas
29
Tema 3
Pilas y Colas
30
Pilas y Colas
31
Tema 3
Pilas y Colas
32
return
>>>hotPotato(['Bill','David','Susan','Jane','Kent','Brad], 7)
Kent
Tema 3
Pilas y Colas
33
Tema 3
Pilas y Colas
34
Dada la clase mazo (Deck ) es el conjunto de cartas de donde sacamos las cartas,
a.Datos:
i. Mazo de cartas
b. Mtodos
i. Constructor crea todas las cartas con nmeros de 0 a 9 y colores.
ii. Obtener la carta i del mazo (__getitem__) devuelve la carta en la posicin i
del mazo.
iii. Retornar cuntas cartas tiene el mazo (len).
iv. Borrar la carta i del mazo (remove).
v. Repartir una carta a un jugador (deal_one_card).
vi. Repartir las cartas (deal) reparte N cartas a cada uno de los jugadores.
Pilas y Colas
35
Colas de prioridad
Tema 3
Pilas y Colas
36
Qu mtodos ha de tener?
Podemos reaprovechar alguna clase?
Qu mtodos redefinir?
Qu mtodos sobrecargar?
Tema 3
Pilas y Colas
37
Pilas y Colas
38
Ejercicio
Tema 3
Pilas y Colas
39
Tema 3
Pilas y Colas
40
Pilas y Colas
41
Tema 3
Pilas y Colas
42
Pilas y Colas
43
Deque
Pilas y Colas
44
El TAD Deque
Pilas y Colas
45
Ejemplo de deque
[]
Operacin
Contenido de la cola
Valor de retorno
[4]
q.isEmpty()
[]
True
[ dog ,4]
q.addRear(4)
[4]
[ dog ,4]
[q.addFront(
dog ,4, cat ,True]
cat )
[d.addFront(True)
dog ,4, cat ,True]
[len(q)
dog ,4, cat ,True]
[8.4,
q.isEmpty()
dog ,4, cat ,True]
False
[q.addRear
dog ,4, cat(8.4)
,True]
[q.removeRear()
dog ,4, cat ]
8.4
[q.removeFront()
dog ,4, cat ]
True
len(q)
Tema 3
Pilas y Colas
46
def __len__(self):
def __str__(self):
Tema 3
Pilas y Colas
class Deque:
def __init__(self):
self._items = []
def isEmpty(self):
return self._items == []
def addFront(self, item):
self._items.append(item)
def addRear(self, item):
self._items.insert(0,item)
def removeFront(self):
return self._items.pop()
def removeRear(self):
return self._items.pop(0)
def __len__(self):
return len(self._items)
def __str__(self):.
Petia Ivanova Radeva
47
Tema 3
Pilas y Colas
48
if first != last:
return stillEqual
Implementar el mismo programa sustituyendo el deque con una pila y una cola.
Tema 3
Pilas y Colas
49
if first != last:
return stillEqual
def palchecker(aString):
chardeque = Deque()
for ch in aString:
chardeque.addRear(ch)
stillEqual = True
while len(chardeque) > 1 and
stillEqual:
first =chardeque.removeFront()
last = chardeque.removeRear()
if first != last:
stillEqual = False
return stillEqual
Pilas y Colas
50
Ser capaz de reconocer las propiedades de los problemas, donde son apropiadas
las pilas, colas, colas de prioridad y deques.
Tema 3
Pilas y Colas
51
Objetivos
Colecciones
Colecciones lineales
Ejemplos ordinarios:
Listas de compra
Pila de platos
Cola de usuarios en el banco
Colecciones jerrquicas
Estructura rbol
Colecciones de grafos
10
Un array es un objeto de tipo coleccin donde todos los elementos estn fsicamente
almacenados en un espacio continuo
Una lista enlazada es un objeto de tipo coleccin donde todos los elementos no
necesariamente estn fsicamente almacenados en un espacio continuo. La relacin entre
los elementos se consigue a travs de sus enlaces
11
vs.
12
12
13
def __iter__(self):
"""Supports traversal with a for
loop."""
return iter(self._items)
def __getitem__(self, index):
"""Subscript operator for access at
index."""
return self._items[index]
def __setitem__(self, index, newItem):
"""Subscript operator for
replacement at index."""
self._items[index] = newItem
def __str__(self):
"""-> The string representation of
the array."""
return str(self._items)
Petia Ivanova Radeva
14
16
1
3
4
5
1
3
4
5
17
17
18
Tamao fsico
Tamao lgico
19
20
1
3
4
5
Consiste en:
Crear un nuevo array ms grande
Copiar los datos del array viejo al nuevo
Reasignar a la variable del viejo array en el nuevo objeto
1
3
4
5
Para conseguir una ejecucin ms razonable, duplicar el tamao del array cada
vez que se incrementa el tamao:
21
1
3
4
5
22
1
3
4
5
15
231
157231
7
23
24
Pasos:
Mover los elementos desde la posicin concreta hasta el final del
tamao lgico con uno
Decrementar el tamao lgico con uno
Comprobar el espacio no utilizado y decrementar el tamao fsico del
array si es necesario
157231
25
26
157231
27
28
Procesando un Grid
29
30
31
32
En una tabla (grid) no uniforme, hay un nmero fijo de filas pero el nmero de
columnas en cada fila puede variar
Estructuras enlazadas
Existen varias caractersticas que se han de tener en cuenta cuando se usan las
estructuras enlazadas para implementar otros tipos
34
Enlace vaco
36
37
class Node:
def __init__(self, data, next=None):
'''Instantiates a Node with default next of None'''
self.__data=data
self.__next=next
def __str__(self):
return str(self.__data)
39
Las variables del Node se inicializan como None o algun otro objeto Node
node1=None
# Just an empty link
node2=Node('a', node1)
# A node containing data and an empty link
node3=Node('b', node2)
# A node containing data and a link to node2
40
->
AttributeError
Solucin:
41
42
La lista enlazada
class LinkedList:
def __init__(self):
self.__head=None
def initialize(self,until):
'''Add X nodes to the linked list'
self.__head=None
for count in xrange(0,until):
self.__head=Node(until-count,self.__head)
def getHead(self):
Returns the first element
return self.__head
43
Recorrido
Ejemplo:
def traverse(self):
probe=self.__head
while probe!= None:
print probe
probe=probe.getNext()
Recorrido
46
Bsqueda
Ejemplo:
def find(self,targetItem):
Bsqueda
probe=self.__head
probe=self.__head
while probe!=None and targetItem!=probe.getData():
probe=probe.getNext()
if probe!=None:
probe.setData(newItem)
return True
else: return False
49
if index<0:
print'Index negativo'
return False
probe=self.__head
while probe!=None and index>=0:
probe=probe.getNext()
index-=1
if index<0:
probe.setData(newItem)
return True
else: return False
Insertar al principio
Insertar al final
52
53
Borrar al Principio
def removeFirst(self):
if self.__head==None: return None
res=self.__head.getData()
self.__head=self.__head.getNext()
54
55
Borrar un elemento del final del array (pop en una lista de Python) requere
tiempo y memoria constante
Siempre y cuando el array no ha de cambiar de tamao
def removeLast(self):
Borra el nodo del final de la estructura
if self.__head==None: return None
if self.__head.getNext()==None:
res, self.__head=self.__head.geData(), None
else:
probe=self.__head
while probe.getNext().getNext()!=None:
probe=probe.getNext()
res=probe.getNext().getData()
probe.setNext(None)
return res
56
57
58
61
62
64
65
def traverseback(self):
Traversing from back to front
probe=self.__tail
while probe!= None:
print probe.getData(),
probe=probe.getPrevious()
66
Tema 3
Pilas y Colas
68
Tema 3
Pilas y Colas
69
Tema 3
Pilas y Colas
70
Resumen
71
Resumen
Las listas circulares y las listas enlazadas dobles permiten moverse en las
dos direcciones con mayor eficiencia
Normalmente, la dualidad del coste en trminos de tiempo y memoria de los
algoritmos
72
Brad Miller, David Ranum, Problem Solving with Algorithms and Data Structures Release 3.0, 2013.
Pat Morin, Open Data Structures (in pseudocode), Edition 0.1G, http://opendatastructures.org.
def __str__(self):
def isEmpty(self):
def push(self, item):
def pop(self):
def peek(self):
def __len__(self):
Tema 3
Pilas y Colas
Pila: Constructor
self.__head
class LinkedStack:
This is a Linked Stack
def __init__(self):
self.__head=None
Pila: push()
self.__head
Pila: push()
self.__head
D
D
D
D
D
Pila: pop()
self.__head
Pila: pop()
self.__head
D
D
D
D
D
def pop(self):
if self.__head==None:
res=None
else:
res=self.__head.getData()
self.__head=self.__head.getNext()
return res
7
Implementacin de la Cola
class Queue:
Define un TDA Cola
def __init__(self):
def __str__(self):
def enqueue(self,el):
def dequeue(self):
def isEmpty(self):
def __len__():
Tema 3
Pilas y Colas
Cola: Constructor
Cuntas variables centinelas
necesitamos?
self.__head
D
self.__tail
class LinkedStack:
This is a Linked Stack
def __init__(self):
self.__head=None
9
Cola: enqueue()
self.__head
D
10
Cola: enqueue ()
self.__head
D
self.__tail
D
12
13
self.__head
14
self.__head
self.__head
15
self.__head
self.__head
16
self.__head
if self.__head==None:
self.__head=Node(data,self.__head)
self.__head.setNext(self.__head)
17
self.__head
18
self.__head
elif self.__head.getNext()==self.__head:
self.__head=Node(data,self.__head)
self.__head.getNext().setNext(self.__head)
19
self.__head
20
self.__head
self.__head=Node(data,self.__head)
probe=self.__head.getNext()
while probe.getNext()!=self.__head:
probe=probe.getNext()
probe.setNext(self.__head)
21
Podemos
ahorrar este
pargrafo?
else:
self.__head=Node(data,self.__head)
probe=self.__head.getNext()
while probe.getNext()!=self.__head:
probe=probe.getNext()
probe.setNext(self.__head)
22
elif self.__head.getNext()==self.__head:
self.__head=Node(data,self.__head)
self.__head.getNext().setNext(self.__head)
else:
self.__head=Node(data,self.__head)
probe=self.__head.getNext()
while probe.getNext()!=self.__head:
probe=probe.getNext()
probe.setNext(self.__head)
23
InsertFront (alternativa)
probe
self.__head
tail
def insertFirst(self,data):
if self.__head==None:
self.__head=Node(data,self.__head)
self.__tail=self.__head
self.__head.setNext(self.__head)
else:
self.__head=Node(data,self.__head)
self.__tail.setNext(self.__head)
24
25
26
class Node:
class TwoWayNode(Node):
def __init__(self,data,previous=None, next=None):
Node.__init__(self,data,next)
self.__previous=previous
27
self.__head
class DoubleLinkedList:
Una lista doblemente
enlazada
def __init__(self):
self.__head=None
28
29
30
self.__head
class DoubleLinkedList:
Una lista doblemente
enlazada
def __init__(self):
self.__head=None
self.__tail=None
31
self.__head
self.__tail
def insertFront(self,data):
self.__head=TwoWayNode(data,None, self.__head)
if self.__head.getNext():
self.__head.getNext().setPrevious(self.__head)
32
D
D
self.__tail
33
Tema 3
Pilas y Colas
34
Tema 3
Pilas y Colas
35
Tema 3
Pilas y Colas
36
Skiplistas
Bi liografa: Pat Morin, Open Data tru tures in pseudo ode , Edition . G
37
Skiplistas
Definicin: una skiplista es una secuencia de listas enlazadas L0, L1, Lr,
donde L0 es la lista original ordenada.
38
Skiplistas
39
40
41
42
43
44
Resumen
Las listas circulares y las listas enlazadas dobles permiten moverse en las dos
direcciones con mayor eficiencia
Normalmente, la dualidad del coste en trminos de tiempo y memoria de los
algoritmos
Las pilas y las colas son fcilmente implementadas como listas enlazadas