IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

sucharge de __eq__


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut sucharge de __eq__
    Bonjour à tous, Bonne et Heureuse Année 2011,
    Je voudrais soumettre à votre sagacité un petit problème qui me turlupine.
    Je suis en train de développer un module de géométrie affine. je dois pouvoir faire de la géométrie dans les espaces K^n où K peut-être soit le corps des réels, soit le corps des complexes, soit le corps des rationnels, soit un corps fini Z/pZ.
    Il faut pour cela définir les vecteurs et les points, si possible avec une seule définition qui marche dans tous les cas de figure, c'est fait !
    Voici le module 'de base' définissant les espaces vectoriels et les espaces affines associés.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    # -*- coding: utf-8 -*-
     
    from fractions import Fraction  #version python >= 2.6
     
    class MyError(Exception):
        """Erreur custom"""
        def __init__(self,value):
            self.value=value
        def __str__(self):
            return repr(self.value)
     
    ######Modélisation des corps Z/pZ avec p premier#####
    def GenZp(p):
        """génère la classe paramétrée Z/pZ"""
        class C(object):
            car=p
            def __init__(self,m):
                """initialisation à partir d'un entier"""
                self.m=m%self.car
            def __str__(self):
                """représentation externe pour print etc..."""
                return str(self.m)
            def __eq__(self,other):
                """test d'égalité"""
                return self.m==other.m
            def nul(self):
                """test de nullité"""
                return self.m==0
            ### les opérateurs unaires
            def __neg__(self):
                """opposé"""
                return C(-self.m)
            def __invert__(self):
                """inverse"""
                if not self.nul():
                    y=1
                    while (self.m*y)%self.car != 1:
                        y+=1
                return C(y)
            ### les opérations binaires
            def __add__(self,other):
                """addition"""
                return C(self.m+other.m)
            def __mul__(self,other):
                """multiplication"""
                if type(self)==type(other):#de deux éléments du même corps
                    return C(self.m*other.m)
                else:#d'un scalaire par un vecteur
                    return other.__rmul__(self)
            def __sub__(self,other):
                """soustraction"""
                return C(self.m-other.m)
            def __div__(self,other):
                return self*~(other)
            def __pow__(self,k):
                """puissances"""
                if k >=0:
                    return C(self.m**k)
                else:
                    return ~self**(-k)
        return C
    #####fin de la modélisation des corps Z/pZ###############################
     
     
     
    ####Espaces vectoriels K^n K corps quelconque n entier quelconque##############
    class VecteurKn:
        """modélisation des vecteurs à n dimensions corps quelconque"""
        def __init__(self,L):
            """constructeur"""
            self.V=L
            self.n=len(L)
        def __str__(self):
            """représentation externe print, etc..."""
            L=[str(x) for x in self.V]
            return '('+ ",".join(L)+')'
        def __eq__(self,other):
            """test d'égalité"""
            return self.n==other.n and all(self.L[i]==other.L[i] for i in xrange(0,self.n))
        def __add__(self,other):
            """addition des vecteurs"""
            if self.n!=other.n:
                raise MyError("Tailles non concordantes")
            else:
                L=[self.V[i]+other.V[i] for i in range(0,self.n)]
                return VecteurKn(L)
        def __neg__(self):
            """opposé d'un vecteur"""
            return VecteurKn([-x for x in self.V])
        def __sub__(self,other):
            """différence de deux vecteurs"""
            return self+(-other)
        def __rmul__(self,k):
            """ produit par un scalaire """
            L=[k*x for x in self.V]
            return VecteurKn(L)
    ####fin de la définition des espaces vectoriels###############
     
    ###########Modélisation des espaces affines###################
    class PointKn:
        """modélisation des espaces affines K^n n et K quelconques"""
        def __init__(self,L):
            """constructeur"""
            self.C=L #coordonnées
            self.n=len(L)
        def __str__(self):
            """représentation externe print, etc..."""
            L=[str(x) for x in self.C]
            return '('+ ",".join(L)+')'
        def __eq__(self,other):
            """test d'égalité"""
            return self.n==other.n and all(self.C[i]==other.C[i] for i in xrange(0,self.n))
        def __add__(self,vecteur):
            """opération du groupe additif des vecteurs"""
            if self.n != vecteur.n:
                raise MyError("Tailles non concordantes")
            else:
                L=[self.C[i]+vecteur.V[i] for i in range(0,self.n)]
                return PointKn(L)
        def __sub__(self,other):
            """vecteur différence de deux points"""
            if self.n != other.n:
                raise MyError("Tailles non concordantes")
            else:
                L=[self.C[i]-other.C[i] for i in range(0,self.n)]
                return VecteurKn(L)
     
    ###fin de la modélisation des espaces affines######################
    Vous remarquerez à ce niveau qu'il y a trois surcharges de l'opérateur __eq__ (pour les corps Z/pZ, pour les vecteurs et pour les points) Ces surcharges fonctionnent comme elles doivent dans des tests naturels.
    Voici maintenant un petit programme d'application visant à déterminer l'intersection de deux plans non parallèles (soit une droite) dans l'espace (Z/3Z)^3.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    # -*- coding: utf-8 -*-
     
    from affines import *
     
    def main():
        CZ3=GenZp(3) #la classe modélisant les éléments Z/3Z
        Z3=[CZ3(x) for x in xrange(0,3)] #le corps Z/3Z entier
        P=PointKn([Z3[1],Z3[2],Z3[1]]) #le point P de l'énoncé
        U=VecteurKn ([Z3[2],Z3[1],Z3[1]]) # le vecteur U de l'énoncé
        V=VecteurKn ([Z3[1],Z3[0],Z3[1]]) # le vecteur V de l'énoncé
        F1=[k*U+h*V for k in Z3 for h in Z3] # le plan vectoriel engendré par U et V
        Q=PointKn([Z3[1],Z3[0],Z3[1]]) #le point Q de l'énoncé
        W=VecteurKn ([Z3[0],Z3[0],Z3[1]]) # le vecteur W de l'énoncé
        T=VecteurKn ([Z3[0],Z3[1],Z3[1]]) # le vecteur W de l'énoncé
        F2=[k*W+h*T for k in Z3 for h in Z3] # plan vectoriel engendré par W et T
        B1=[P+x for x in F1] # le premier plan affine
        B2=[Q+x for x in F2] # le second plan affine
        INTER=[M for M in B1 if any(M==N for N in B2)]
        for M in INTER:#liste les points de l'intersection
            print M
     
    if __name__ == "__main__":
        main()
    J'en viens au point qui me dérange.
    J'avais tout naturellement et dans un premier temps défini INTER (ma droite intersection) par une 'list comprehension'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    INTER=[M for M in B1 if M in B2]
    en pensant que le filtre 'if M in B2' allait se baser sur ma surcharge de __equ__ .
    Grosse déception !
    Le filtre se base sur l'égalité des adresses (bref sur le '==' standard). Quelqu'un sait-il pourquoi ? J'ai trouvé une solution à ma façon qui force le test '==' surchargé (voir code) mais c'est inélégant. Quelqu'un a--t-il une solution meilleure ?
    NB: Pour vous éviter de perdre du temps.
    Passer par 'set' ne résout rien :
    B1=set(B1) -->TypeError: unhashable instance
    Il y a de très fortes restrictions sur les types des objets pouvant être mis en 'sets'.
    ,
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  2. #2
    Membre Expert Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Par défaut
    Salut Zavonen et meilleurs voeux à toi.

    J'avoue que tout ça me dépasse un peu...
    Regarde peut être du côté de __contains__.

  3. #3
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Bonjour et merci à toi Pacificator.
    Je viens d'essayer et ça ne marche pas.
    Je me doute que dans l'implémentation du 'in' des 'list comprehension' il y a appel à __contains__ et la cause est la même.
    Je pense que dans l'implémentation on omet tout simplement de vérifier s'il n'existe pas une surcharge de __eq__
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  4. #4
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Bonjour,
    ne serait-ce pas dû à l'utilisation de hash pour les appartenance et les ensembles ?

  5. #5
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonsoir,

    Je me permets juste un passage pour vous demander une explication du problème plus détaillée en fin de sujet.
    Je m'explique:
    Pour moi un [M for M in B1 if M in B2] ou un [M for M in B1 if any(M==N for N in B2)] donne le même résultat avec le code donné.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (1,2,1)
    (1,0,0)
    (1,1,2)
    Un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        def __eq__(self,other):
            #return self.n==other.n and all(self.C[i]==other.C[i] for i in xrange(0,self.n))
            return False
    Montre l'exécution du code.
    Merci.

  6. #6
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Pour moi un [M for M in B1 if M in B2] ou un [M for M in B1 if any(M==N for N in B2)] donne le même résultat avec le code donné.
    Pas chez moi (Python 2.6 sous linux ubuntu 10.04 LTS lucid) le premier donne la liste vide et le second la bonne réponse.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  7. #7
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Citation Envoyé par rambc Voir le message
    Bonjour,
    ne serait-ce pas dû à l'utilisation de hash pour les appartenance et les ensembles ?
    C'est un problème connu, python ne veut pas d'objets 'mutables' dans les 'sets'. Mais ce n'est pas mon problème.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

Discussions similaires

  1. Réponses: 4
    Dernier message: 25/06/2009, 00h37
  2. Programme reactif meme en cas de sucharge du cpu
    Par azamharir dans le forum MFC
    Réponses: 4
    Dernier message: 29/09/2008, 15h48
  3. Sucharger un TreeNode
    Par rvzip64 dans le forum Composants VCL
    Réponses: 15
    Dernier message: 21/09/2007, 21h14
  4. Sucharge de methode
    Par parisjohn dans le forum Général Python
    Réponses: 4
    Dernier message: 29/06/2007, 14h23
  5. Sucharger une TShape
    Par smail25 dans le forum C++Builder
    Réponses: 3
    Dernier message: 08/03/2005, 20h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo