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 :

Appeller une methode d'une class via une autre methode de la meme class


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    18
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 18
    Points : 15
    Points
    15
    Par défaut Appeller une methode d'une class via une autre methode de la meme class
    bonjour

    je m'essaye la creation de classe, mais j'ai déjà un soucis... je n'arrive pas à utiliser une methode de ma class dans une autre methode de ma class... le code : http://dpaste.com/90970/

    Ce qui pose probleme c'est que mon print mes_data.coord_elm_pdf(25) ne m'affiche que des listes vides et que mon print lst_coord1 est lui aussi vide alors qu'il ne devrait pas...

    Merci

    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
     
    class Data_Pdf:
        """classe representant les elements data d'un objet table de reportlab """
        def __init__(self,data_lst):
            """constructeur de l'objet """
            self._data_lst = data_lst
     
        def _lst_index_elm_list (self,elmt, liste):
            """methode qui trouve les index dans une liste d'une liste d'element"""
     
            data2 = liste
            lst_index =[]
     
            while data2.count(elmt) !=0 :
     
                id1=data2.index(elmt)
     
                lst_index.append(id1)
                data2[id1]='0'
     
            return lst_index
     
        def nbr_col (self) :
            self._nbr_col = len (self._data_lst[0])
            return self._nbr_col
     
        def nbr_lign (self) :
            self._nbr_ligne = len (self._data_lst)
            return self._nbr_ligne
     
        def coord_elm (self,elmt):
            x =0
            lst_coord1 =[]
            nbr_col = self.nbr_col()
            nbr_ligne = self.nbr_lign()
            for elm in self._data_lst :
     
     
                lst_y = self._lst_index_elm_list (elmt, elm)
     
                for elm in lst_y :
                    coord1 =(x,elm)
                    lst_coord1.append(coord1)
                x=x+1
            return lst_coord1
     
        def coord_elm_pdf (self,elmt) :
     
     
            lst_coord1 = self.coord_elm(elmt)
            print lst_coord1
            lst_coord_pdf =[]
            for elm in lst_coord1 :
     
                x2 = nbr_col-elm[0]
                y2 = nbr_ligne-elm[1]
                coord2 =(-x2,-y2)
                lst_coord_pdf.append((elm,coord2))
     
     
            return lst_coord_pdf
            pass
        def coord_elm_col (self) :
            pass
     
     
     
     
     
     
     
     
     
     
     
    data = [ [50,25,50],[100,25,25],[80,20,20],[150,10,2] ]
     
     
     
    mes_data = Data_Pdf (data)
    print mes_data
    print mes_data.nbr_col()
    print mes_data.nbr_lign()
    print mes_data.coord_elm(25)
    print mes_data.coord_elm(50)
    print mes_data.coord_elm_pdf(25)

  2. #2
    Membre éprouvé
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Points : 1 066
    Points
    1 066
    Par défaut
    Ta question est vague, et ton code est, à mon goût bien sur, illisible.
    A quelle ligne se situe ton problème d'"utilisation de méthode" ? Est-ce l'appel, la valeur de retour qui pose problème ?

  3. #3
    Membre chevronné

    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
    Points : 1 752
    Points
    1 752
    Par défaut
    Il faudrait proposer un ECM (Exemple Colmplet Minimal) qui montre ton problème car moi non plus je n'ai pas le courage de lire tes lignes de code.

  4. #4
    Membre habitué
    Inscrit en
    Mars 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2003
    Messages : 127
    Points : 149
    Points
    149
    Par défaut
    j'ai lancé rapidemnt ton code est l'erreur est toute béte
    tu a modifié ta list de référence
    quand tu lance la premiére fois ta fonction
    _lst_index_elm_list
    l'attribut self._data_lst contient ça
    [[50, 25, 50], [100, 25, 25], [80, 20, 20], [150, 10, 2]]

    quant tu repasse pour obtenir le résultat de
    print mes_data.coord_elm_pdf(25)
    ta list self._data_lst contient ça
    [['0', '0', '0'], [100, '0', '0'], [80, 20, 20], [150, 10, 2]]
    Donc si tu ne veux pas avoir ces petit soucie des type mutable je te conseil de regarde le module copy
    Sinon ton algorithme me semble pas trop pythonique

  5. #5
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Moi par contre, j’adore analyser des codes quand j’ai le temps. Ça me délasse

    Bon, je réagis à mesure que je lis ton code.



    Il y a plusieurs choses qui ne vont pas dans
    def _lst_index_elm_list (self,elmt, liste):



    1) Dans while data2.count(elmt) !=0 :
    count() compte tous les elmt dans data2 pour savoir s’il en reste dans la liste data2, et pour ce faire, count() est obligé de parcourir l’intégralité de la liste jusqu’au dernier élément.
    Ceci à chaque tour de while.
    Sachant qu’ensuite, c’est index() qui reparcourt une portion plus ou moins longue de la liste pour trouver où se trouve le premier elmt dans la liste.
    Tout cela est beaucoup de travail, redondant.

    Alors qu’il suffit de savoir s’il en reste au moins un ou pas du tout.
    Ce qui s’établit plus simplement par un test dont l’exécution est beaucoup plus rapide que celle de count():
    Mais réitérer ce test continuellement n’est pas encore la meilleure solution. Car même s’il est plus rapide, il reste que ce test et index() parcourent toujours plusieurs fois la liste.

    Il faut chercher à ne la parcourir qu’une fois.



    2) Quand data2.index(elmt) est exécutée, la fonction index() fait sa recherche en commençant par le début de la liste data2.

    Ce qui veut dire qu’à chaque nouvelle liste data2 ( issue de la précedente par élimination du premier elmt qui avait été précédemment rencontré par index() ), la fonction index() reparcourt le début de data2:
    - elle parcourt donc plusieurs fois les mêmes élements de data2
    - elles les parcourt alors qu’il n’y a plus de elmt parmi eux, puisqu’ils sont au fur et à mesure enlevés

    Par dessus le marché, index() est assez lente à se mouvoir dans une liste.

    Donc algorithme pas bon.



    Une solution de courte-vue:

    il ne faut pas jeter id1, il faut l’utiliser comme repère pour redémarrer l’analyse de data2 par index() . Mais attention, le fait d’enlever un élément de data2 décale de -1 les valeurs des index des éléments suivants. Donc il faut être finaud.
    Mais c’est un remède très médiocre.




    Ce qui ne va pas basiquement pas dans le code de cette fonction, c’est que index() itère sur les éléments de la liste, dit la position de l’élément recherché, et s’arrête.

    Ce qui conduit à enlever un élément une fois que la détection a eu lieu pour chercher le suivant. Ce qui conduit encore à créer un double, data2, de la liste originale pour ne pas l’altérer.

    Quand on s’enfonce comme ça dans des contorsions en cascade, c’est qu’il y a un truc qui ne va pas. Parfois, ça sert de se dire: et si je faisais l’inverse ?

    OK, allons-y: itérons non plus sur les éléments de la liste mais sur les positions. Et détectons donc quand l’élément à la position examinée est égal à celui voulu. Et paf ça donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        def _lst_index_elm_list (self,elmt, liste):
            lst_index =[]
            for i in xrange(len(liste)):
                if liste[i]==elmt:
                    lst_index.append(i)
            return lst_index

    3) Il y a encore mieux à faire en recourant à une list comprehension:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        def _lst_index_elm_list (self,elmt, liste):
            return [ i for i in xrange(len(liste)) if liste[i]==elmt ]

    4) Quand tu écris data2 = liste , cela ne crée pas une seconde liste identique et indépendante de la première.

    Cela crée une étiquette ’data2’ qui est collée à l’objet liste qui portait déjà comme étiquette le nom ’liste’: il s’agit d’aliasing sur un même objet, et non pas d’une duplication d’objet.

    Ce qui entraîne que toute modification ciblée vers data2 atteint en réalité le seul objet ayant les deux noms ’data2’ et ’liste’.

  6. #6
    Membre habitué
    Inscrit en
    Mars 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2003
    Messages : 127
    Points : 149
    Points
    149
    Par défaut
    Je propose ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> data = [ [50,25,50],[100,25,25],[80,20,20],[150,10,2] ]
    >>> list = []
    >>> [ list.extend([(index1,index2) for index2,item2 in enumerate(item1) if item2 == 25]) for index1,item1 in enumerate(data)] 
    [None, None, None, None]
    >>> list
    [(0, 1), (1, 1), (1, 2)]
    Même si j'aime pas le list.extend dans la liste compréhension mais j'ai pas en tête une fonction pour sommer des listes :/

    edit un truc un peu plus jolie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> def extend_plus(a,b): 
    ...     a.extend(b)
    ...     return a 
    reduce(extend_plus, [ list.extend([(index1,index2) for index2,item2 in enumerate(item1) if item2 == 25]) for index1,item1 in enumerate(data)] ,[])

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    18
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 18
    Points : 15
    Points
    15
    Par défaut
    Merci à tous pour vos remarques constructives... j'ai bien conscience que mon code est très loin d'etre optimisé... en fait c'est le premier jet... je fais toujours un premier code qui fonctionne et ensuite j'essaye de l'améliorer...

    Dans ce cas là, il ne fonctionnait pas... JE vais regarder avec toutes vos remarques et revenir vers vous lorsque j'aurai fait tourner tout ça...

    Merci à toutes et tous

    lo

  8. #8
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    PS 1
    Tant qu’à faire, il est inutile de créer spécialement une fonction
    _lst_index_elm_list (self, elmt, liste)

    Il faut reporter la list comprehension directement à l’endroit où cette fonction était nécessaire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            for elm in self._data_lst :
     
                #lst_y = self._lst_index_elm_list (elmt, elm)
                lst_y = [ i for i in xrange(len(elm)) if elm[i]==elmt ]



    PS 2
    Je pense que la ligne
    for elm in lst_y :
    dans la fonction def coord_elm (self,elmt):
    est une erreur.

    Elle est en effet placée dans une boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for elm in self._data_lst :
    qui itère sur les sous-listes de la liste data.

    Après la première valeur self._data_lst[0] prise par elm , cette ligne fait brusquement prendre à elm la valeur lst_y[0] , qui est d’ailleurs un indice.

    Ça marchera mieux avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
                for y in lst_y :
                    coord1 =(x,y)
                    lst_coord1.append(coord1)

    À ce propos, il ne faut pas dépythoniser ton code:
    au lieu de ci-dessus, pourquoi ne pas écrire au plus court ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                for y in lst_y :
                    lst_coord1.append((x,y))

  9. #9
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    PS 3

    L’avantage de Python, c’est qu’une fois qu’on a épuré certains bouts du code, on s’aperçoit qu’on peut faire encore plus direct.... et qu’on s’était vraiment compliqué les choses:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        def coord_elm (self,elmt):
            x =0
            lst_coord1 =[]
            nbr_col = self.nbr_col()
            nbr_ligne = self.nbr_lign()
            for elm in self._data_lst :
                lst_y = [ i for i in xrange(len(elm)) if elm[i]==elmt ]
                for y in lst_y :
                    lst_coord1.append((x,y))
                x=x+1
            return lst_coord1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        def coord_elm (self,elmt):
            x =0
            lst_coord1 =[]
            nbr_col = self.nbr_col()
            nbr_ligne = self.nbr_lign()
            for elm in self._data_lst :
                for y in xrange(len(elm)):
                    if elm[y]==elmt:
                        lst_coord1.append((x,y))
                x=x+1
            return lst_coord1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        def coord_elm (self,elmt):
            x =0
            lst_coord1 =[]
            nbr_col = self.nbr_col()
            nbr_ligne = self.nbr_lign()
            for elm in self._data_lst :
                lst_coord1.extend( [ (x,y) for y in xrange(len(elm)) if elm[y]==elmt ] )
                x=x+1
            return lst_coord1


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        def coord_elm (self,elmt):
            nbr_col = self.nbr_col()
            nbr_ligne = self.nbr_lign()
            lst_coord1 = [ (self._data_lst.index(elm),y)\
                           for elm in self._data_lst\
                           for y in xrange(len(elm)) if elm[y]==elmt ]
            return lst_coord1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
         def coord_elm (self,elmt):
            nbr_col = self.nbr_col()
            nbr_ligne = self.nbr_lign()
            return [ (self._data_lst.index(elm),y)\
                     for elm in self._data_lst\
                     for y in xrange(len(elm)) if elm[y]==elmt ]

    Euh...à quoi servent nbr_col et nbr_ligne dans def coord_elm (self,elmt): ?


    PS 4
    Arrivé à ce stade, on peut encore se demander, comme l’a fait apparemment Tyrus, si on ne peut pas prendre un chemin algorithmique un peu différent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
         def coord_elm (self,elmt):
            nbr_col = self.nbr_col()
            nbr_ligne = self.nbr_lign()
            return [ (x,y)\
                     for x,elm in enumerate(self._data_lst)\
                     for y,elem in enumerate(elm) if elem==elmt ]
    NB : enumerate() est une fonction très rapide


    suite
    On peut ensuite s’attaquer à simplifier def coord_elm_pdf (self,elmt) ........
    Je te laisse faire

  10. #10
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Je n’ai pas pu résister à la tentation de tout simplifier, en définitive.

    J’ai injecté un peu de mathématique pour vidanger un peu de code.
    Voici ce que ça donne:

    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
    from operator import concat
     
    class Data_Pdf:
        """classe representant les elements data d'un objet table de reportlab """
     
        def __init__(self,data_lst):
            self._data_lst = data_lst
            self._nbr_col = len (data_lst[0])
            self._nbr_ligne = len (data_lst)
            self._defrag_list = reduce(concat,data_lst)
     
        def coord_elm (self,elmt):
            return [ divmod(i,3) for i,u in enumerate(self._defrag_list) if u==elmt ]
     
        def coord_elm_pdf (self,elmt) :
            return [ (q - self._nbr_ligne, r - self._nbr_col) for (q,r) in self.coord_elm(elmt) ]
     
     
    data = [ [50,25,50],[100,25,25],[80,20,20],[150,10,2] ]
     
    mes_data = Data_Pdf (data)
     
    print '_data_list   :\n',mes_data._data_lst
    print '_nbr_ligne   :',mes_data._nbr_ligne,'(nombre de sous-listes)'
    print '_nbr_col     :',mes_data._nbr_col,"(nombre d'elements dans les sous-listes)"
    print '_defrag_list :\n',mes_data._defrag_list
     
    print '\ncoord_elm de 25'
    print mes_data.coord_elm(25)
    print 'coord_elm de 50'
    print mes_data.coord_elm(50)
    print 'coord_elm_pdf de 25'
    print mes_data.coord_elm_pdf(25)
    _data_list :
    [[50, 25, 50], [100, 25, 25], [80, 20, 20], [150, 10, 2]]
    _nbr_ligne : 4 (nombre de sous-listes)
    _nbr_col : 3 (nombre d'elements dans les sous-listes)
    _defrag_list :
    [50, 25, 50, 100, 25, 25, 80, 20, 20, 150, 10, 2]

    coord_elm de 25
    [(0, 1), (1, 1), (1, 2)]
    coord_elm de 50
    [(0, 0), (0, 2)]
    coord_elm_pdf de 25
    [(-4, -2), (-3, -2), (-3, -1)]
    Explication:

    divmod(i,3) donne le tuple (i//3,i%3) c’est à dire le quotient et le reste de la division euclidienne de i par 3,
    soit (4,1) pour divmod(13,3)
    (4,2) pour divmod(14,3) etc

    La liste _defrag_list est
    [50, 25, 50, 100, 25, 25, 80, 20, 20, 150, 10, 2]

    Les indices i des éléments de cette liste sont
    0 1 2 3 4 5 6 7 8 9 10 11

    La liste des divmod(i,3) des i de cette liste est
    (0, 0) (0, 1) (0, 2) (1, 0) (1, 1) (1, 2) (2, 0) (2, 1) (2, 2) (3, 0) (3, 1) (3, 2)
    ce qui correspond au repérage de chaque élément par la fonction coord_elm()

    Parallèlement, le repérage correspondant par la fonction coord_elm_pdf() est le suivant:
    (-4,-3) (-4,-2) (-4,-1) (-3,-3) (-3,-2) (-3,-1) (-2,-3) (-2,-2) (-2,-1) (-1,-3) (-1,-2) (-1,-1)

    On voit que si on appelle (a,b) un repère donné par coord_elm() et (-pa,-pb) le repère correspondant donné par coord_elm_pdf(), on a:
    a + pa = 4
    b + pb = 3
    donc
    -pa , -pb = a-4, b-3




    Si les listes data que tu as à traiter réellement sont grandes, je pense que tu aurais intérêt à déduire des tableaux Numpy ardata de tes listes data et de faire les traitements sous numpy: plus rapide.




    PS

    Tout ce code est basé sur l’idée que les sous-listes de data ont toutes le même nombre d’éléments.
    Ce qui me semble la conclusion inévitable du fait que tu as écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self._nbr_col = len (data_lst[0] )
    Évidemment, si cette hypothèse n’était pas toujours respectée, la validité de ce code s’écroulerait.

  11. #11
    Membre habitué
    Inscrit en
    Mars 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2003
    Messages : 127
    Points : 149
    Points
    149
    Par défaut
    Bourrin mais jolie

  12. #12
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Bourin ?

    Je pense que tu as raison pour coord_elm_pdf(), Tyrus: il est inutile d’itérer sur self._defrag_lst pour créer une liste de (r,q) dans laquelle il faut ensuite itérer;
    tant qu’à devoir itérer dans self._defrag_lst, autant calculer tout de suite les coordonnées ’inverses’ pour les seuls u==elmt.

    J’ai un peu simplifié les notations; je ne choisirais pas des notations aussi tarabiscotées, personnellement.

    Y a-t-il une raison de mettre un underscore _ après self. ?

    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
    from operator import concat
     
    class Data_Pdf:
        """classe representant les elements data d'un objet table de reportlab """
     
        def __init__(self,data_lst):
            self._data_lst = data_lst
            self._ncol = len (data_lst[0])
            self._nligne = len (data_lst)
            self._defraglist = reduce(concat,data_lst)
     
        def coord_elm (self,elmt):
            return [ divmod(i,self._ncol) for i,u in enumerate(self._defraglist) if u==elmt ]
     
        def coord_elm_pdf (self,elmt) :
            return [ (i//self._ncol - self._nligne, i%self._ncol - self._ncol) for i,u in enumerate(self._defraglist) if u==elmt ]
     
     
    data = [ [50,25,50],[100,25,25],[80,20,20],[150,10,2] ]
     
    mes_data = Data_Pdf (data)
     
    print '_data_list   :\n',mes_data._data_lst
    print '_nligne   :',mes_data._nligne,'(nombre de sous-listes)'
    print '_ncol     :',mes_data._ncol,"(nombre d'elements dans les sous-listes)"
    print '_defraglist :\n',mes_data._defraglist
     
    print '\ncoord_elm de 25'
    print mes_data.coord_elm(25)
    print 'coord_elm de 50'
    print mes_data.coord_elm(50)
    print 'coord_elm_pdf de 25'
    print mes_data.coord_elm_pdf(25)

  13. #13
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Je n’étais pas satisfait de l’expression alambiquée
    (i//self._ncol - self._nligne, i%self._ncol - self._ncol)

    J’ai cherché autre chose —> j’ai créé la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        def coord2(self,i):
            u,v = divmod(self._derpos - i, self._ncol)
            return (-u-1,-v-1)
    Cette fonction nécessite le dernier indice de position
    self._derpos = len(self._defraglist) - 1 de la liste self._defraglist (valeur 11 dans l'exemple),
    de façon à obtenir la succession d’indices 11,10,9,8,7,6,5,4,3,2,1,0 comme correspondant à l’itération dans self._defraglist,
    pour pouvoir calculer les “coordonnées“ du deuxième type (celles négatives (-4,-2), (-3,-1) etc).

    En appliquant divmod(x,3) à cette succession, on obtient
    (3, 2) (3, 1) (3, 0) (2, 2) (2, 1) (2, 0) (1, 2) (1, 1) (1, 0) (0, 2) (0, 1) (0, 0)
    qui réclame ensuite un décalage de 1 et les mettre en négatif pour obtenir
    (-4, -3) (-4, -2) (-4, -1) (-3, -3) (-3, -2) (-3, -1) (-2, -3) (-2, -2) (-2, -1) (-1, -3) (-1, -2) (-1, -1)






    J’ai aussi regardé si l’utilisation d’un itérateur pour obtenir des i,u successifs pouvait être plus rapide que enumerate().




    J’ai testé toutes les possibilités avec le code suivant:

    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
    from operator import concat
    from itertools import ifilter
    from time import clock
     
    class Data_Pdf(object):
        """classe representant les elements data d'un objet table de reportlab """
     
        def __init__(self,data_lst):
            self._data_lst = data_lst
            self._ncol = len (data_lst[0])
            self._nligne = len (data_lst)
            self._defraglist = reduce(concat,data_lst)
            self._derpos = len(self._defraglist) - 1
     
        def coord2(self,i):
            u,v = divmod(self._derpos - i, self._ncol)
            return (-u-1,-v-1)
     
     
     
        def coord_elm(self,elmt):
            return [ divmod(i,self._ncol) for i,u in enumerate(self._defraglist) if u==elmt ]
     
        def coord_elm_pdf_0(self,elmt) :
            return [ (i//self._ncol - self._nligne, i%self._ncol - self._ncol) for i,u in enumerate(self._defraglist) if u==elmt ]
     
        def coord_elm_pdf(self,elmt) :
            return [ self.coord2(i) for i,u in enumerate(self._defraglist) if u==elmt ]
     
     
     
        def coord_elm_DEUX(self,elmt):
            return [ divmod(i,self._ncol) for i,u in ifilter(lambda x: x[1]==elmt,enumerate(self._defraglist)) ]
     
        def coord_elm_pdf_0_DEUX(self,elmt):
            return [ (i//self._ncol - self._nligne, i%self._ncol - self._ncol) for i,u in ifilter(lambda x: x[1]==elmt,enumerate(self._defraglist)) ]
     
        def coord_elm_pdf_DEUX(self,elmt) :
            return [ self.coord2(i) for i,u in ifilter(lambda x: x[1]==elmt,enumerate(self._defraglist)) ]
     
     
    data = [ [50,25,50],[100,25,25],[80,20,20],[150,10,2] ]
     
    mes_data = Data_Pdf (data)
     
    print '_data_list  :',mes_data._data_lst
    print '_nligne     :',mes_data._nligne,'(nombre de sous-listes)'
    print '_ncol       :',mes_data._ncol,"(nombre d'elements dans les sous-listes)"
    print '_defraglist :',mes_data._defraglist
     
    print '\ncoord_elm de 25'
    te = clock()
    print mes_data.coord_elm(25)
    tf = clock()
    print tf-te
    print 'coord_elm_DEUX de 25'
    te = clock()
    print mes_data.coord_elm_DEUX(25)
    tf = clock()
    print tf-te
     
    print '\ncoord_elm_pdf_0 de 25'
    te = clock()
    print mes_data.coord_elm_pdf_0(25)
    tf = clock()
    print tf-te
    print 'coord_elm_pdf_0_DEUX de 25'
    te = clock()
    print mes_data.coord_elm_pdf_0_DEUX(25)
    tf = clock()
    print tf-te
     
     
    print '\ncoord_elm_pdf de 25'
    te = clock()
    print mes_data.coord_elm_pdf(25)
    tf = clock()
    print tf-te
    print 'coord_elm_pdf_DEUX de 25'
    te = clock()
    print mes_data.coord_elm_pdf_DEUX(25)
    tf = clock()
    print tf-te

    _data_list : [[50, 25, 50], [100, 25, 25], [80, 20, 20], [150, 10, 2]]
    _nligne : 4 (nombre de sous-listes)
    _ncol : 3 (nombre d'elements dans les sous-listes)
    _defraglist : [50, 25, 50, 100, 25, 25, 80, 20, 20, 150, 10, 2]
    _lendefrag : 11

    coord_elm de 25
    [(0, 1), (1, 1), (1, 2)]
    0.0106130807128
    coord_elm_DEUX de 25
    [(0, 1), (1, 1), (1, 2)]
    0.0104354044997

    coord_elm_pdf_0 de 25
    [(-4, -2), (-3, -2), (-3, -1)]
    0.0111919252307
    coord_elm_pdf_0_DEUX de 25
    [(-4, -2), (-3, -2), (-3, -1)]
    0.0107066680263

    coord_elm_pdf de 25
    [(-4, -2), (-3, -2), (-3, -1)]
    0.0105924076943
    coord_elm_pdf_DEUX de 25
    [(-4, -2), (-3, -2), (-3, -1)]
    0.0113536776322

    Tous les temps sont les mêmes.

    Il en résulte que la fonction coord2() n’apporte ni gain ni perte de temps par rapport à la formule alambiquée.

    Idem pour ifilter() par rapport à enumerate().



    La fonction coord2() rend le code plus lisible d’après moi.
    La meilleure solution est donc:

    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
    from operator import concat
     
    class Data_Pdf(object):
        """classe representant les elements data d'un objet table de reportlab """
     
        def __init__(self,data_lst):
            self._data_lst = data_lst
            self._ncol = len (data_lst[0])
            self._nligne = len (data_lst)
            self._defraglist = reduce(concat,data_lst)
            self._derpos = len(self._defraglist) - 1
     
        def coord2(self,i):
            u,v = divmod(self._derpos - i, self._ncol)
            return (-u-1,-v-1)
     
        def coord_elm(self,elmt):
            return [ divmod(i,self._ncol) for i,u in enumerate(self._defraglist) if u==elmt ]
     
        def coord_elm_pdf(self,elmt) :
            return [ self.coord2(i) for i,u in enumerate(self._defraglist) if u==elmt ]
     
    data = [ [50,25,50],[100,25,25],[80,20,20],[150,10,2] ]
     
    mes_data = Data_Pdf (data)
     
    print '_data_list  :',mes_data._data_lst
    print '_nligne     :',mes_data._nligne,'(nombre de sous-listes)'
    print '_ncol       :',mes_data._ncol,"(nombre d'elements dans les sous-listes)"
    print '_defraglist :',mes_data._defraglist
     
    print '\ncoord_elm de 25'
    print mes_data.coord_elm(25)
     
    print '\ncoord_elm_pdf de 25'
    print mes_data.coord_elm_pdf(25)
    Je pense qu’il n’y a pas plus concis et plus efficace.

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    18
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 18
    Points : 15
    Points
    15
    Par défaut
    Wahoo ! tant de passion ça fait plaisir... j'ai pas encore eu le temps de regarder tout ça... je m'y attelle des demain... en tout cas, merci, car avec cette exemple précis, je vais pouvoir mieux cerner ce qu'est le développement python...

    Merci

  15. #15
    Membre habitué
    Inscrit en
    Mars 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2003
    Messages : 127
    Points : 149
    Points
    149
    Par défaut
    eyquemtu n'avais pas assez de valeur pour faire un test j'ai multiplié la liste data par 10000 et j'obtiens ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    coord_elm de 25
    0.050000
    coord_elm_DEUX de 25
    0.070000
     
    coord_elm_pdf_0 de 25
    0.040000
    coord_elm_pdf_0_DEUX de 25
    0.080000
     
    coord_elm_pdf de 25
    0.060000
    coord_elm_pdf_DEUX de 25
    0.110000

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 11/10/2012, 20h01
  2. Réponses: 2
    Dernier message: 17/04/2007, 17h14
  3. Réponses: 4
    Dernier message: 28/03/2007, 22h23
  4. Réponses: 5
    Dernier message: 10/11/2006, 11h00
  5. Réponses: 6
    Dernier message: 09/11/2005, 17h29

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