[débutant] problème avec dictionnaires
Le
chahnaz.ourzikene
salut à tous,
j'ai un probleme avec les dicionnaires. Je vous explique :
J'ai créer les classes suivantes :
(j'utilise le mot 'abstrait' pour dire 'non visuel', pas dans le sens
objet 'abstrait')
Point : modélise un point abstrait.
VisualElement : cette classe définit un élement visuel abstrait (au
sens objet cette fois-ci). La méthode principale de cette classe est
'respresent(abstractObject)' qui prends en argument un objet abstrait
a représenter à l'écran , et qui le lie à l'objet visuelle qui le
represente (l'instance appelante). Cette liaison est implémentée sous forme
de dictionnaire associatif où les clés seraient les objets abstraits (les
points) et où les valeurs seraient les élements visuels (points visuels).
VisualPoint(Point) : représentation visuelle d'un point (abstrait dans le
sens non visuel) à l'écran. Dérive de la
classe Point
Le problème c'est que quand j'essaye de lier un objet abstrait à un
objet visuel à l'aide de la méthode VisualElement.represent(), j'ai une
exception du type : 'unhashable instance'
Voici l'appelant qui déclanche l'exception :
class VisualPoint (VisualElement,Point):
def __init__(self,application,P=Point(),ray,color="red") :
"""
arguments are : the application using the visual point, the point
represented,
and it's color (red by default)
"""
VisualElement.__init__(self,application,color)
Point.__init__(self,P.x,P.y)
###> ci-dessous la ligne appelante :
self.represent(P)
self.ULx = P.x - ray
self.ULy = P.y - ray
self.BRx = P.x + ray
self.BRy = P.y + ray
Voici la classe qui possède cette méthode :
class VisualElement :
representants = {}
def __init__(self,application,color="black") :
self.app = application
self.item_n = 0
self.color = color
def represent(self,abstractObject) :
""" this methode attaches a Visual Element to an abstract object
passed as an argument"""
self.represented = abstractObject
###> la ligne ci-aprés déclanche l'excpetion :
VisualElement.representants[abstractObject] = self
Toute aide sera grandement appréciée.
Le code en entier pour ceux qui veulent debuger :
from Tkinter import *
class Point :
def __init__ (self,x=0,y=0) :
self.x = x
self.y = y
def squareDistTo(self,P) :
return ((self.x - P.x) * (self.x - P.x)) + ((self.y - P.y) * (self.y - P.y))
def farestOf(self,list) :
"""list is a list of points to search in """
for P in list :
dist = self.squareDistTo(l)
if dist > farestDist :
farestDist = dist
farestPoint = P
return P
def __eq__(self,P):
return P.x==self.x and P.y==self.y
class Edge :
def __init__ (self,A,B) :
""" x and y are the coordinates of the vector, A and B are vertices of the
edge """
self.x=B.x-A.x
self.y=B.y-A.y
self.A=A
self.B=B
def findFarest(self,galaxy) :
""" finds the farest point of galaxy from self"""
farestDist = 0
farestPoint = None
for P in galaxy :
if P == self.A or P == self.B :
continue
d1 = self.A.squareDistTo(P)
d2 = self.B.squareDistTo(P)
d = d1+d2
if d > farestDist :
farestDist = d
farestPoint = P
return farestPoint
def isOnTheRight(self,P):
""" useful to know wether P is outside the convex hull or not
returns true if outside
"""
return (self.x*P.y-self.y*P.x)>0
def intersectPoint(self,L):
""" this methode returns the intersection point between the instance and the
Line L
and the t factor which is used to determine wether the intersection point is
on both
edges or not (must be 0 < t <= 0 """
a=self.x
b=self.y
c= a*self.A.x + b*self.B.y
if not (a*L.x + b*L.y == 0) :
t= - (a*L.A.x + b*L.A.Y + c) / (a*L.x + b*L.y)
ix = L.A.x + t*L.x
iy = L.A.y + t*L.y
return Point(ix,iy) , t
return None
def intersectPointOnEdge(self,E) :
""" returns the intersection point between two edges or None """
P,t= self.intersectPoint(E)
if 0 <= t <= 1 :
return P
return None
class Galaxy :
def __init__(self):
self.Points=[]
def addPoint(self,P):
self.Points.append(P)
def removePointAt(self,x,y):
i = 0
for p in Points :
if p.x == x and p.y == y :
del Points[i]
i = i+1
class Hull (Galaxy) :
def __init__(self,P):
"""
a Point must be given to set the highest/lowest coordinates of the
leftmost/rightmost
point correctly.
this :
"self.leftmost_P = self.rightmost_P = P"
is better than :
"
self.leftmost_P = Point(10000000,10000000)
self.rightmost_P = Point(-1000000,-1000000)
"
for example
"""
Galaxy.__init__(self)
self.leftmost_P = self.rightmost_P = P
def findExtrema(self):
for p in Points :
if p.x >= self.rightmost_P.x :
self.rightmost_P = p
if p.y <= self.leftmost_P.x :
self.leftmost_P = p
return self.leftmost_P, self.rightmost_P
class VisualElement :
representants = {}
def __init__(self,application,color="black") :
self.app = application
self.item_n = 0
self.color = color
def represent(self,abstractObject) :
""" this methode attaches a Visual Element to an AbstractObject passed as an
argument"""
self.represented = abstractObject
VisualElement.representants[abstractObject] = self
def representant(self,abstractObject) :
"""
this methode returns the visual element representing an abstract object
passed as
an argument
"""
return VisualElement.representants[abstractObject]
def represented(self) :
"""
this methode returns the abstract object represented by self
(an instance of visual element)
"""
return self.represented
def delete(self):
""" this methode deletes the calling Visual Element"""
del VisualElement.representants[self.represented]
self.canv.delete(self.item_n)
def erase (self) :
""" this methode do not delete the calling Visual Element, it makes the
illusion of
disapearing from the screen by redrawing the visual element with the
background color.
"""
self.draw(color=self.app.canv.cget("bg"))
def getItemNum (self) :
return self.item_n
def changeColor(self,color):
self.color = color
self.app.canv.itemconfig(self.item_n,fill=self.color)
#def configure(self,exp):
# self.canv.itemconfig(self.item_n, exp)
class VisualPoint (VisualElement,Point):
def __init__(self,application,P=Point(),ray,color="red") :
"""
arguments are : the application using the visual point, the point
represented,
and it's color (red by default)
"""
VisualElement.__init__(self,application,color)
Point.__init__(self,P.x,P.y)
self.represent(P)
self.ULx = P.x - ray
self.ULy = P.y - ray
self.BRx = P.x + ray
self.BRy = P.y + ray
def draw(self):
self.item_n=self.canv.create_oval(self.ULx,self.ULy,self.BRx,self.BRy,
fill=self.color)
class VisualEdge(VisualElement, Edge) :
""" Represents an edge on the screen"""
def __init__(self,application,edge,color="black"):
VisualElement.__init__(application,color)
Edge.__init__(edge.A,edge.B)
self.represent(edge)
self.item_n=0
def draw(self):
item_n=self.app.canv.create_line(self.A.x,self.A.y,self.B.x,self.B.y,color=s
elf.color)
class VisualHull(VisualElement,Hull):
""" Represents a Hull on the screen, needs an Application as a parameter """
def __init__(self,application) :
VisualElement.__init__(self,application)
Hull.__init__(self)
self.V_leftmost_P = VisualPoint(self.app)
self.V_rightmost_P = VisualPoint(self.app)
def addPoint(self,P) :
""" Warning : P must be of type Point, VisualPoints are not suitable """
Galaxy.addPoint(P)
VP = VisualPoint(self.app)
VP.represent(P)
#self.VPoints.append(VP)
def findExtrema(self) :
"""
finds the rightmost and the leftmost points of the hull and returns visual
points
representing them
"""
leftmost,rightmost = Hull.findExtrema(self)
return self.representant(leftmost), self.representant(righmost)
class Application (Frame) :
""" this is the application master class """
FIRST_CLICK = 0
CREATION = 1
DRAW_HULL = 2
P_RAY = 5
P_INTERSPACE = 1.5 * P_RAY
def __init__(self,w = 500,h P0) :
### Graphical initialisation
Frame.__init__(self)
self.canvÊnvas(self,width = w, height = h, bg = "ivory")
self.canv.pack(padx=3,pady=5)
self.canv.bind("<Button-1>",self.first_click)
self.canv.grid(row=1,columnspan=2)
self.quickhull = Button(self,command=self.do_quickhull, text="Convex
Polygon")
self.quickhull.grid(row=2,column=0,pady=5)
self.quit=Button(self,command=self.quit,text="Quit")
self.quit.grid(row=2,column=1,pady=5)
#self.reset=Button(self,command=self.reset,text="Reset")
#self.reset.grid(row=2,column=3)
self.rightmost_P_view = Label(self)
self.rightmost_P_view.grid(row=3,columnspan=2)
self.leftmost_P_view = Label(self)
self.leftmost_P_view.grid(row=4,columnspan=2)
self.element_view = Label(self)
self.element_view.grid(row=5,columnspan=2)
self.vhull_view=Label(self)
self.vhull_view.grid(row=6,columnspan=2)
self.mode = self.CREATION
self.pack()
### Other initalisations
self.V_last_rightmost_P = VisualPoint(self)
self.V_last_leftmost_P = VisualPoint(self)
def first_click(self,e) :
"""
this is an internal methode. It handles the first click on the canvas to
create the
visual hull of the application with the inital point as an argument. See the
__init__
methode of the Hull class for more details.
"""
#self.MODE = CREATION
self.vhull = VisualHull(self,Point(e.x,e.y))
self.canv.bind("<Button-1>",self.mouse_click)
def mouse_click(self,e) :
"""mouse click handler for the canvas"""
if self.mode == self.CREATION :
element = self.canv.find_overlapping(
e.x-self.P_INTERSPACE,e.y-self.P_INTERSPACE,e.x+self.P_INTERSPACE,e.y+self.P
_INTERSPACE)
self.element_view.configure(text=element)
if not element :
P= Point(e.x,e.y)
self.vhull.addPoint(P)
VP = self.createVisualPoint(P)
VP.draw()
self.V_last_leftmost_P.changeColor("red")
self.V_last_rightmost_P.changeColor("red")
self.V_last_leftmost_P, self.V_last_rightmost_P = self.vhull.findExtrema()
self.V_last_rightmost_P.changeColor("green")
self.V_last_leftmost_P.changeColor("blue")
self.leftmost_P_view.configure(
text= "Leftmost Point is at : "+str(self.last_leftmost_P.x) + " "
+str(self.last_leftmost_P.y))
self.rightmost_P_view.configure(
text="Rightmost Point is at : "+str(self.last_rightmost_P.x) + " "
+str(self.last_rightmost_P.y))
def createVisualPoint (self,onePoint) :
return VisualPoint(P=onePoint,ray=self.P_RAY)
def do_quickhull(self) :
self.vhull.findExtrema()
VisualEdge(Edge(self.vhull.leftmost_P,self.vhull.rightmost_P),self).draw()
#if __name__ == "main" :
hull = Application()
hull.mainloop()
j'ai un probleme avec les dicionnaires. Je vous explique :
J'ai créer les classes suivantes :
(j'utilise le mot 'abstrait' pour dire 'non visuel', pas dans le sens
objet 'abstrait')
Point : modélise un point abstrait.
VisualElement : cette classe définit un élement visuel abstrait (au
sens objet cette fois-ci). La méthode principale de cette classe est
'respresent(abstractObject)' qui prends en argument un objet abstrait
a représenter à l'écran , et qui le lie à l'objet visuelle qui le
represente (l'instance appelante). Cette liaison est implémentée sous forme
de dictionnaire associatif où les clés seraient les objets abstraits (les
points) et où les valeurs seraient les élements visuels (points visuels).
VisualPoint(Point) : représentation visuelle d'un point (abstrait dans le
sens non visuel) à l'écran. Dérive de la
classe Point
Le problème c'est que quand j'essaye de lier un objet abstrait à un
objet visuel à l'aide de la méthode VisualElement.represent(), j'ai une
exception du type : 'unhashable instance'
Voici l'appelant qui déclanche l'exception :
class VisualPoint (VisualElement,Point):
def __init__(self,application,P=Point(),ray,color="red") :
"""
arguments are : the application using the visual point, the point
represented,
and it's color (red by default)
"""
VisualElement.__init__(self,application,color)
Point.__init__(self,P.x,P.y)
###> ci-dessous la ligne appelante :
self.represent(P)
self.ULx = P.x - ray
self.ULy = P.y - ray
self.BRx = P.x + ray
self.BRy = P.y + ray
Voici la classe qui possède cette méthode :
class VisualElement :
representants = {}
def __init__(self,application,color="black") :
self.app = application
self.item_n = 0
self.color = color
def represent(self,abstractObject) :
""" this methode attaches a Visual Element to an abstract object
passed as an argument"""
self.represented = abstractObject
###> la ligne ci-aprés déclanche l'excpetion :
VisualElement.representants[abstractObject] = self
Toute aide sera grandement appréciée.
Le code en entier pour ceux qui veulent debuger :
from Tkinter import *
class Point :
def __init__ (self,x=0,y=0) :
self.x = x
self.y = y
def squareDistTo(self,P) :
return ((self.x - P.x) * (self.x - P.x)) + ((self.y - P.y) * (self.y - P.y))
def farestOf(self,list) :
"""list is a list of points to search in """
for P in list :
dist = self.squareDistTo(l)
if dist > farestDist :
farestDist = dist
farestPoint = P
return P
def __eq__(self,P):
return P.x==self.x and P.y==self.y
class Edge :
def __init__ (self,A,B) :
""" x and y are the coordinates of the vector, A and B are vertices of the
edge """
self.x=B.x-A.x
self.y=B.y-A.y
self.A=A
self.B=B
def findFarest(self,galaxy) :
""" finds the farest point of galaxy from self"""
farestDist = 0
farestPoint = None
for P in galaxy :
if P == self.A or P == self.B :
continue
d1 = self.A.squareDistTo(P)
d2 = self.B.squareDistTo(P)
d = d1+d2
if d > farestDist :
farestDist = d
farestPoint = P
return farestPoint
def isOnTheRight(self,P):
""" useful to know wether P is outside the convex hull or not
returns true if outside
"""
return (self.x*P.y-self.y*P.x)>0
def intersectPoint(self,L):
""" this methode returns the intersection point between the instance and the
Line L
and the t factor which is used to determine wether the intersection point is
on both
edges or not (must be 0 < t <= 0 """
a=self.x
b=self.y
c= a*self.A.x + b*self.B.y
if not (a*L.x + b*L.y == 0) :
t= - (a*L.A.x + b*L.A.Y + c) / (a*L.x + b*L.y)
ix = L.A.x + t*L.x
iy = L.A.y + t*L.y
return Point(ix,iy) , t
return None
def intersectPointOnEdge(self,E) :
""" returns the intersection point between two edges or None """
P,t= self.intersectPoint(E)
if 0 <= t <= 1 :
return P
return None
class Galaxy :
def __init__(self):
self.Points=[]
def addPoint(self,P):
self.Points.append(P)
def removePointAt(self,x,y):
i = 0
for p in Points :
if p.x == x and p.y == y :
del Points[i]
i = i+1
class Hull (Galaxy) :
def __init__(self,P):
"""
a Point must be given to set the highest/lowest coordinates of the
leftmost/rightmost
point correctly.
this :
"self.leftmost_P = self.rightmost_P = P"
is better than :
"
self.leftmost_P = Point(10000000,10000000)
self.rightmost_P = Point(-1000000,-1000000)
"
for example
"""
Galaxy.__init__(self)
self.leftmost_P = self.rightmost_P = P
def findExtrema(self):
for p in Points :
if p.x >= self.rightmost_P.x :
self.rightmost_P = p
if p.y <= self.leftmost_P.x :
self.leftmost_P = p
return self.leftmost_P, self.rightmost_P
class VisualElement :
representants = {}
def __init__(self,application,color="black") :
self.app = application
self.item_n = 0
self.color = color
def represent(self,abstractObject) :
""" this methode attaches a Visual Element to an AbstractObject passed as an
argument"""
self.represented = abstractObject
VisualElement.representants[abstractObject] = self
def representant(self,abstractObject) :
"""
this methode returns the visual element representing an abstract object
passed as
an argument
"""
return VisualElement.representants[abstractObject]
def represented(self) :
"""
this methode returns the abstract object represented by self
(an instance of visual element)
"""
return self.represented
def delete(self):
""" this methode deletes the calling Visual Element"""
del VisualElement.representants[self.represented]
self.canv.delete(self.item_n)
def erase (self) :
""" this methode do not delete the calling Visual Element, it makes the
illusion of
disapearing from the screen by redrawing the visual element with the
background color.
"""
self.draw(color=self.app.canv.cget("bg"))
def getItemNum (self) :
return self.item_n
def changeColor(self,color):
self.color = color
self.app.canv.itemconfig(self.item_n,fill=self.color)
#def configure(self,exp):
# self.canv.itemconfig(self.item_n, exp)
class VisualPoint (VisualElement,Point):
def __init__(self,application,P=Point(),ray,color="red") :
"""
arguments are : the application using the visual point, the point
represented,
and it's color (red by default)
"""
VisualElement.__init__(self,application,color)
Point.__init__(self,P.x,P.y)
self.represent(P)
self.ULx = P.x - ray
self.ULy = P.y - ray
self.BRx = P.x + ray
self.BRy = P.y + ray
def draw(self):
self.item_n=self.canv.create_oval(self.ULx,self.ULy,self.BRx,self.BRy,
fill=self.color)
class VisualEdge(VisualElement, Edge) :
""" Represents an edge on the screen"""
def __init__(self,application,edge,color="black"):
VisualElement.__init__(application,color)
Edge.__init__(edge.A,edge.B)
self.represent(edge)
self.item_n=0
def draw(self):
item_n=self.app.canv.create_line(self.A.x,self.A.y,self.B.x,self.B.y,color=s
elf.color)
class VisualHull(VisualElement,Hull):
""" Represents a Hull on the screen, needs an Application as a parameter """
def __init__(self,application) :
VisualElement.__init__(self,application)
Hull.__init__(self)
self.V_leftmost_P = VisualPoint(self.app)
self.V_rightmost_P = VisualPoint(self.app)
def addPoint(self,P) :
""" Warning : P must be of type Point, VisualPoints are not suitable """
Galaxy.addPoint(P)
VP = VisualPoint(self.app)
VP.represent(P)
#self.VPoints.append(VP)
def findExtrema(self) :
"""
finds the rightmost and the leftmost points of the hull and returns visual
points
representing them
"""
leftmost,rightmost = Hull.findExtrema(self)
return self.representant(leftmost), self.representant(righmost)
class Application (Frame) :
""" this is the application master class """
FIRST_CLICK = 0
CREATION = 1
DRAW_HULL = 2
P_RAY = 5
P_INTERSPACE = 1.5 * P_RAY
def __init__(self,w = 500,h P0) :
### Graphical initialisation
Frame.__init__(self)
self.canvÊnvas(self,width = w, height = h, bg = "ivory")
self.canv.pack(padx=3,pady=5)
self.canv.bind("<Button-1>",self.first_click)
self.canv.grid(row=1,columnspan=2)
self.quickhull = Button(self,command=self.do_quickhull, text="Convex
Polygon")
self.quickhull.grid(row=2,column=0,pady=5)
self.quit=Button(self,command=self.quit,text="Quit")
self.quit.grid(row=2,column=1,pady=5)
#self.reset=Button(self,command=self.reset,text="Reset")
#self.reset.grid(row=2,column=3)
self.rightmost_P_view = Label(self)
self.rightmost_P_view.grid(row=3,columnspan=2)
self.leftmost_P_view = Label(self)
self.leftmost_P_view.grid(row=4,columnspan=2)
self.element_view = Label(self)
self.element_view.grid(row=5,columnspan=2)
self.vhull_view=Label(self)
self.vhull_view.grid(row=6,columnspan=2)
self.mode = self.CREATION
self.pack()
### Other initalisations
self.V_last_rightmost_P = VisualPoint(self)
self.V_last_leftmost_P = VisualPoint(self)
def first_click(self,e) :
"""
this is an internal methode. It handles the first click on the canvas to
create the
visual hull of the application with the inital point as an argument. See the
__init__
methode of the Hull class for more details.
"""
#self.MODE = CREATION
self.vhull = VisualHull(self,Point(e.x,e.y))
self.canv.bind("<Button-1>",self.mouse_click)
def mouse_click(self,e) :
"""mouse click handler for the canvas"""
if self.mode == self.CREATION :
element = self.canv.find_overlapping(
e.x-self.P_INTERSPACE,e.y-self.P_INTERSPACE,e.x+self.P_INTERSPACE,e.y+self.P
_INTERSPACE)
self.element_view.configure(text=element)
if not element :
P= Point(e.x,e.y)
self.vhull.addPoint(P)
VP = self.createVisualPoint(P)
VP.draw()
self.V_last_leftmost_P.changeColor("red")
self.V_last_rightmost_P.changeColor("red")
self.V_last_leftmost_P, self.V_last_rightmost_P = self.vhull.findExtrema()
self.V_last_rightmost_P.changeColor("green")
self.V_last_leftmost_P.changeColor("blue")
self.leftmost_P_view.configure(
text= "Leftmost Point is at : "+str(self.last_leftmost_P.x) + " "
+str(self.last_leftmost_P.y))
self.rightmost_P_view.configure(
text="Rightmost Point is at : "+str(self.last_rightmost_P.x) + " "
+str(self.last_rightmost_P.y))
def createVisualPoint (self,onePoint) :
return VisualPoint(P=onePoint,ray=self.P_RAY)
def do_quickhull(self) :
self.vhull.findExtrema()
VisualEdge(Edge(self.vhull.leftmost_P,self.vhull.rightmost_P),self).draw()
#if __name__ == "main" :
hull = Application()
hull.mainloop()

Poser une question


dictionnaire .. plutôt que des objects
tu peux utiliser le nom de l'objet par exemple ..
class VisualElement(object): # cela en jette pour peu d'effort !
d'instruction global et c'est bien
Et que se passe-t-il si list est vide ?
import Numeric as N
suivi de help(N) on devrait trouver son bonheur.
Si on veut en gérer beaucoup pas besoin de sortir l'artillerie objet, on
peut se contenter d'un bon tuple des familles (x, y) ou avoir un "axe"
dans un Numeric.array qui contiendrait tous les points considérés.
du genre : points = N.array(coords, N.Float) ou N.Integer
Avec un Numeric.array ou même un array.array vous gagnez éventuellement
pas mal de place en mémoire car tous les éléments sont forcément du même
type et donc cette information de type n'est pas dupliquée pour chaque
élément.
ne s'impose pas. Vous b'auriez pas fait beaucoup de java dans une vie
antérieure ? (:-) et quelle expérience avez-vous en Fortran ?
Il y a plus loin dans le code une utilisation subtile de méthode et
d'attribut avec le même nom (ou presque) qui m'échappe.
Je vous conseillerais de passer pylint sur votre module et de poser
votre question lorsque pylint vous donnera un score d'au moins 7
(j'esp-re que vous n'utilisez pas les tabulations pour indenter car
alors votre premier score pylint sera négatif) (pylint est sur logilab.org)
Cordialement.
C'est un problème de concéption (peut être aurais-je dû faire l'analyse
avant...). Je conçois un VisualPoint comme étant une spécification de Point.
Il se compose de cooronnées (x,y), et de quelques attributs supplémentaires
qui permettent de l'afficher correctement sur un écran et de pouvoir le
retrouver facilement (pour lui changer de couleur par exemple ou de
taille...). Or, la couleur, la taille, et l'affichage à l'écran ne concerne
pas uniquement les points visuels, mais aussi un grand nombre d'éléments
visuels. D'où l'idée de créer une classe abstraite d'objets visuels. Cette
classe regroupe donc tous les attributs nécessaires pour la visualition à
l'écran. C'est donc pour ces raisons que VisualPoint dérive à la fois de
Point et de VisualElement.
Voir plus haut. Mais peut être qu'une solution plus simple existe !
Je n'ai pas encore eu l'occasion d'étudier cette classe. Un internaute m'a
suggérer sur le forum dédié à python du site www.developpez.com d'utiliser
justement ce type de classe pour que ma fonction de hachage puisse se faire
sans difficulté sur mes objets, du moment qu'ils en héritent. (la classe
object implémente une methode __hash__ il me semble...).
Désolé ! ça doit être mon bloc note windows... (je le copie d'un fichier
écrit sous emacs sur linux).
C'est une erreur, merci de l'avoir signalé. le bon argument est P bien sûre.
Non, autre erreur. Elle doit être initialisée à 0. Le code n'est pas fini
car je suis bloqué par cet affaire de dictionnaire !!
J'essaye d'éviter au maximum le couplage pour un maximum de cohésion. (c'est
bien les bons termes ??)
le return P ne se fait qu'à la sortie de la boucle for. Si la liste est vide
P devrait valoir None... ( à gérer par l'appelant ). Je pense que le mieux
c'est de lever une exception.
Je ne connais pas encore les différents modules python, ni toutes les
structures de données et classes buil-in qu'il supporte.
ça pourrait être une solution, mais je préfère (essayer de) mener la logique
objet jusqu'au bout dans mon application.
C'est encore pire, j'ai fait beaucoup de C ! passer de la conception
fonctionnelle et l'analyse structurelle à l'analyse et la conception objet
n'a pas été trés evidente. Avant python j'ai essayé le C++ et ça m'a fait un
peu d'entrainement pour aborder la POO.
Ce que je fais souvent c'est donner le même nom à un attribut d'instance et
à un argument de méthode. Ce que je fais moins souvent c'est de donner le
même nom à un attribut d'instance et à une méthode... ça serait quand même
un peu confus, et pour moi, et pour l'interprete python qui n'aurait
surement pas apprécié.
pylint est un outil d'analyse de code python ?
Sous emacs c'est quand même plus pratique de mettre des tabulations...
surtout que je crois qu'il les converti automatiquement en 4 espaces
blancs..(à vérifier..)
Merci d'avoir pris la peine d'analyser le code et d'avoir pris la peine de
le lire. Merci pour également pour vos suggestions.
Y.Chaouche.
objets a été lancée sur fr.comp.objet.
Toute personne interessée est invitée à participer.
Y.Chaouche.
conception, spécification, ... Vous devriez vous essayer à la méthodologie
Merise que des mauvaises langues de l'époque ont appelée "Méthode éprouvée
pour Retarder Indéfiniment la Sortie des études" ;-)
simplement obtenus par obj.nom (les noms d'attributs sont les clés de
obj.__dict__) Autrement dit :
class ElementVisuel(object):
"""simplement un vrac d'attributs pour élément susceptible d'être
affiché
"""
pass # pas de code
pt = ElementVisuel()
pt.x, pt.y = (100, 150)
# Tiens ce peut être un Point
pt.color = "red" # ou RGB(...) ou ....
Ce qui importe c'est le nom donné à l'attribut (et son existence bien
sûr). pylint va un peu râler que les attributs ne sont pas définis dans
la méthode __init__ mais ce n'est pas nécessaire : en python on crée des
objets à la volée et on les modifie dynamiquement (par exemple en
ajoutant des attributs)
le python cookbook, ou d'autres explications très pertinentes de cet
Italien très cultivé sur les méthodes "Easier to ask forgiveness than
permission" ou "Leap before je-ne-sais-plus-quoi"
et les propriétés que doivent avoir un objet pour être utilisé comme clé
d'un dictionnaire. On y lit entre autre
Objects which compare equal must have same hash value
An object's hash value must never change during it's lifetime (et en
fait tant qu'il est utilisé comme clé)
(slrn est un lecteur de news (NNTP) en mode texte)
des tests et on passe la batterie de tests.
collection.
vous ajoutez une méthode qui vous semble bien pratique mais qui vous
casse la baraque : la règle citée plus haut n'est plus respectée et
python gueule (trp fort ce python). On peut peut-être rattraper le coup
soit en supprimant cette méthode __eq__, soit en codant une méthode
__hash__ compatible :
def __hash__(self):
return hash((self.x, self.y)) # utilisation d'un tuple
pas testé.
en français sur http://www.design-up.com ) c'est qu'il vaut mieux être
fainéant, en faire le moins possible : ne coder que ce qui est
strictement nécessaire pour que ça tourne, mais on code de nombreux
tests unitaires pour vérifier que cela fait ce qu'on veut et que cela
rejette de mauvaises entrées/manipulations (en levant les exceptions
adéquates par exemple).
l'instance (ou de la classe d'ailleurs) qui est "callable". Il est donc
impossible d'avoir le même nom pour un attribut d'instance et une
méthode, c'est le dernier lien (binding) qui compte.
et les erreurs dans farestOf auraient été signalés.