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 :

Utilisation join sur une liste imbriquée


Sujet :

Python

  1. #1
    Membre éclairé Avatar de Marcopololo
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 311
    Par défaut Utilisation join sur une liste imbriquée
    Bonjour,
    Je cherche à afficher dans une boite de dialogue les informations de ma liste.
    Si ma liste est du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     fields= ['parcelles_Travaux_Date1','parcelles_Travaux_Date2','parcelles_Travaux_Travaux2']
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    fields= [
                        ['parcelles_Travaux_Date1','parcelles_Travaux_Travaux1']
                        ]
    cela fonctionne.
    Mais dès que ma liste contient deux colonnes j'ai une erreur de type
    TypeError: QgsFeature.__getitem__(): arguments did not match any overloaded call:
    overload 1: argument 1 has unexpected type 'list'
    overload 2: argument 1 has unexpected type 'list'


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     def build_travaux_dates(e):
                    fields= [
                        ['parcelles_Travaux_Date1','parcelles_Travaux_Travaux1'],
                        ['parcelles_Travaux_Date2','parcelles_Travaux_Travaux2']
                        ]
     
                    to_str = " : ".join([e[field] for field in fields if e[field]])
                    if not to_str:
                        return 'Aucun travaux effectués ici...'
                    return to_str
                self.dlg.tavauxListe.setText(build_travaux_dates(e))
    J'ai aussi essayé d'utiliser deux listes différentes 'Travaux_Date' et Travaux_Travaux avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.dlg.tavauxListe.setText(build_travaux_dates(e)  + " : " + str(build_travaux_parcelles(e)))
    dans ma boite de dialogue et en prenant la même structure pour les deux listes, cela fonctionne sauf qu'il me met tous les champs dates puis les champs travaux

    Merci d'avance de votre aide

    Merci de votre aide
    Marcopololo

  2. #2
    Membre actif
    Homme Profil pro
    Animateur Numérique
    Inscrit en
    Février 2013
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Animateur Numérique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2013
    Messages : 142
    Par défaut
    Citation Envoyé par Marcopololo Voir le message
    Mais dès que ma liste contient deux colonnes j'ai une erreur de type
    TypeError: QgsFeature.__getitem__(): arguments did not match any overloaded call:
    overload 1: argument 1 has unexpected type 'list'
    overload 2: argument 1 has unexpected type 'list'
    Salut,

    Il faut itérer sur tes sous listes, en supposant que ton dictionnaire "e" a une structure classique :
    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
     
    e = {
        'parcelles_Travaux_Date1': '14/04/2025',
        'parcelles_Travaux_Travaux1': 'Labour',
        'parcelles_Travaux_Date2': '18/06/2025',
        'parcelles_Travaux_Travaux2': 'Semis'
    }
     
    def build_travaux_dates(e):
        fields = [
            ['parcelles_Travaux_Date1', 'parcelles_Travaux_Travaux1'],
            ['parcelles_Travaux_Date2', 'parcelles_Travaux_Travaux2']
        ]
     
        for sublist in fields:
            to_str = " : ".join([e[field] for field in sublist if e[field]])
            print(to_str)
     
    build_travaux_dates(e)

  3. #3
    Membre éclairé Avatar de Marcopololo
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 311
    Par défaut
    Merci beaucoup, le code fonctionne les valeurs s'affichent bien dans la console mais j'ai systématiquement "Aucun travaux effectués ici..." qui s'affiche dans ma boite de dialogue.
    Ma liste est bien du style classique

    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
                def build_travaux_dates(e):
                    #fields = fields.strftime("%d/%m/%Y")
                    fields= [
                        ['parcelles_Travaux_Date1','parcelles_Travaux_Travaux1'],
                        ['parcelles_Travaux_Date2','parcelles_Travaux_Travaux2'],
                        ['parcelles_Travaux_Date3','parcelles_Travaux_Travaux3'],
                        ['parcelles_Travaux_Date4','parcelles_Travaux_Travaux4'],
                        ['parcelles_Travaux_Date5','parcelles_Travaux_Travaux5'],
                        ['parcelles_Travaux_Date6','parcelles_Travaux_Travaux6']
                    ]
                    for sublist in fields:
                        to_str =  " : ".join([e[field] for field in sublist if e[field]])
                        if not to_str:
                            return 'Aucun travaux effectués ici...'
                        print (to_str)
                    return to_str
                self.dlg.tavauxListe.setText(build_travaux_dates(e))

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 034
    Par défaut
    Hello,

    Sans connaître le type de e je ne vois pas comment on pourrait répondre à cela...

    Pour moi, j'ai l'impression que vous considérez e comme un dictionnaire, alors que ce message d'erreur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TypeError: QgsFeature.__getitem__(): arguments did not match any overloaded call
    pourrait venir de la ligne e[field]
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  5. #5
    Membre éclairé Avatar de Marcopololo
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 311
    Par défaut
    J'espère que je vais réussir à expliquer, découvrant python.
    e correspond aux champs définis dans fields du style '25/02/2024' pour les dates et des chaines de caractères pour l'autre champ.
    Vous avez surement raison car dans la console j'ai fait un code similaire mais avec des données directement dedans et il fonctionne.
    Et le après return affiche bien les valeurs de ma table.

    Ce code sur une seule colonne fonctionne, alors je l'ai reproduit mais avec des doutes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
                def build_liste_arbres(e):
                    fields = [
                        'liste_arbres_Plant1', #sapin
                        'liste_arbres_Plant2', #mélèze
                        'liste_arbres_Plant3', #chênes
                        'liste_arbres_Plant4'  #épicéas
                    ]
                    to_str = "\n".join([e[field] for field in fields if e[field]])
                    if not to_str:
                        return 'Aucune essence définie ici...'
                    return to_str
                self.dlg.plantation.setText(build_liste_arbres(e))

  6. #6
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 284
    Par défaut
    bonjour

    on tourne en rond, comme déjà indiqué, ici tout depend de e, et c'est justement cela que tu ne donnes pas.
    Mais vu ton code actuel, je suppose que ton véritable problème est justement la stucture de e car ta structure fields avec des dates et travaux n'est pas logique.
    $moi= (:nono: !== :oops:) ? :king: : :triste: ;

  7. #7
    Membre éclairé Avatar de Marcopololo
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 311
    Par défaut
    Citation Envoyé par papajoker Voir le message
    bonjour

    on tourne en rond, comme déjà indiqué, ici tout depend de e, et c'est justement cela que tu ne donnes pas.
    Mais vu ton code actuel, je suppose que ton véritable problème est justement la stucture de e car ta structure fields avec des dates et travaux n'est pas logique.
    Je n'avais pas bien compris je pense que c'est l'origine de e qu'il faut ?
    Pour essayé de l'expliquer, e correspond aux entités de ma feuille d'attribut (QGIS) en lien avec la zone cliquée.

    Pourtant si je simplifie ma liste fields en prenant uniquement "parcelles_travaux_date1, parcelles_travaux_date2,..." ou "parcelles_travaux_travaux1,..." les données s'affiche bien dans ma boite de dialogue

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        def display_point(self, point, button):
            """Affiche les coordonnées du clic"""
            self.dlg.hide()  # cache la boite de dialogue
            couche_parcelles = QgsProject.instance().mapLayersByName("parcelles moyenmoutier")[0]
            req = QgsFeatureRequest().setFilterRect(QgsGeometry.fromPointXY(QgsPointXY(point.x(), point.y())).boundingBox())
     
            entites = couche_parcelles.getFeatures(req)
            for e in entites:
                self.dlg.coordClick.setText(
                    f"{point.x()}, {point.y()}")  # affichage des coordonnées dans la boite de dialogue
                self.dlg.numParc.setText(e['id'])
                self.dlg.coord2.setText(e['section'] + e['numero'])
                self.dlg.surface.setText((str(e['SURFACE'])) +' ares')
                self.dlg.annee.setText((str(e['liste_arbres_Annee'])))

  8. #8
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 284
    Par défaut
    regarde mon exemple (et exécute le !) ...

    tout depend de la structure de e ! et ensuite, si on a une bonne structure, il est extrêmement simple d'avoir des filtres (requetes)
    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
    e = [
        {"date": "2025", "travail": "maison", "parcelle": "A45", "plus": "..."},
        {"date": "2025", "travail": "jardin", "parcelle": "A44", "plus": "..."},
        {"date": "2024", "travail": "maison", "parcelle": "A45", "plus": "..."},
    ]
     
     
    def filtre(e, condition):
        tmps = e
        if "date" in condition:
            tmps = [x for x in e if x["date"] == condition["date"]]
        if "travail" in condition:
            tmps = [x for x in tmps if x["travail"] == condition["travail"]]
        if "parcelle" in condition:
            tmps = [x for x in tmps if x["parcelle"] == condition["parcelle"]]
        return tmps
     
     
    results = filtre(e, {"date": "2025"})
    print("en 2025", results)
     
    results = filtre(e, {"travail": "maison"})
    print("a la maison", results)
     
    results = filtre(e, {"date": "2024", "travail": "maison"})
    print("a la maison en 2024", results)
     
    results = filtre(e, {"parcelle": "A44"})
    print("sur la parcelle A44", results)
    $moi= (:nono: !== :oops:) ? :king: : :triste: ;

  9. #9
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 034
    Par défaut
    Où est exécutée cette fonction build_liste_arbres car cette fonction demande un paramètre e. Donc soit vous avez une fonction qui retourne e et donc on a son type, soit vous utilisez e dans une fonction et on ne voit pas quelle est cette fonction (peut-être display_point ?).

    En regardant la méthode getFeatures et l'erreur QgsFeature.__getitem__() ... j'ai le gros pressentiment que e est un objet QgsFeature et que vous devriez regarder sa documentation pour savoir quels sont les types d'objets acceptés par la méthode __getitem__, représenté par un appel e[type].
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  10. #10
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 284
    Par défaut
    si e est un tableau de QgsFeature,
    le filtre plus haut, peut être une chose du type ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if "date" in condition:
       tmps = [x for x in e if x.attribute("date") == condition["date"]]
    comme l'écrit Ferd, ici ton problème est de bien utiliser ta bibliothèque, lire la doc est un pré requis.
    $moi= (:nono: !== :oops:) ? :king: : :triste: ;

  11. #11
    Membre éclairé Avatar de Marcopololo
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 311
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Où est exécutée cette fonction build_liste_arbres car cette fonction demande un paramètre e. Donc soit vous avez une fonction qui retourne e et donc on a son type, soit vous utilisez e dans une fonction et on ne voit pas quelle est cette fonction (peut-être display_point ?).

    En regardant la méthode getFeatures et l'erreur QgsFeature.__getitem__() ... j'ai le gros pressentiment que e est un objet QgsFeature et que vous devriez regarder sa documentation pour savoir quels sont les types d'objets acceptés par la méthode __getitem__, représenté par un appel e[type].
    Oui e est un objet de QgsFeatures qui se créé dans displaypoint et qui correspond à tous les attributs de ma table récupérés en fonction du click et des coordonnées de ma couche.
    Je vais regarder les documentations pour essayé de comprendre. La première partie display_point provient d'exemples et de corrections qui ont été apportés. Ma maitrise python est très rudimentaire et je comprends tout doucement la philosophie.
    Et je vais aussi essayé les exemples donnés par papajoker.
    Et vous avez raison depuis le début quand j'ai voulu essayé avec une table imbriquée j'ai eu des soucis.
    Et de la même manière, si je mets mes données en une seule colonne cela fonctionne, il y a juste un soucis d'affichage, les données se mettent les unes en dessous des autres. J'a ila solution de faire deux zones d'affichage mais j'aimerais comprendre pourquoi cela ne fonctionne pas.

    en tout cas merci de votre aide

  12. #12
    Membre éclairé Avatar de Marcopololo
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 311
    Par défaut
    Bonjour,

    Après avoir lu de nombreuses choses, et compris quelques unes, et utilisé vos propositions je suis arrivé à cela :
    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
                def build_travaux_dates(e):
                    # fields = fields.strftime("%d/%m/%Y")
                    fields = [
                        'parcelles_Travaux_Date1',
                        'parcelles_Travaux_Travaux1',
                        'parcelles_Travaux_Date2',
                        'parcelles_Travaux_Travaux2',
                        'parcelles_Travaux_Date3',
                        'parcelles_Travaux_Travaux3',
                        'parcelles_Travaux_Date4',
                        'parcelles_Travaux_Travaux4',
                        'parcelles_Travaux_Date5',
                        'parcelles_Travaux_Travaux5',
                        'parcelles_Travaux_Date6',
                        'parcelles_Travaux_Travaux6'
                    ]
                    to_str = " : ".join([e[field] for field in fields if e[field]])
                    print("str:",to_str)
                    if not to_str:
                        return 'Aucun travaux effectués ici...'
                    lg=len(fields)
                    print(lg)
                    to_tbl = to_str.split(" : ")
                    #print(to_tbl)
                    for i in range(lg,0,-2):
                        to_tbl.insert(i-1," : ")
                        to_tbl.insert(i+1,"\n")
                        print ("to_tbl:",to_tbl)
                        to_str2 = "".join(to_tbl)
                        print("to_str2:",to_str2)
                        #print("list:", list(map(str,to_str2)))
                    return to_str
                    #print("list:",list(to_str2))
                    #self.dlg.travauxListe.setText(list(to_str2))
                self.dlg.travauxListe.setText(build_travaux_dates(e))
    Il ne me reste plus qu'à trouvé la solution, comment récupéré les infos de str2 pour les afficher dans ma boite de dialogue.
    Et effectivement le problème venait de e. e étant les données de ma table attributaire qui correspondent à la zone cliqué, sauf qu'il est impossible d'écrire dans cette table, d'où les ller et retour pour avoir l'ensemble des données.
    Bon le code n'est peut être pas très beau mais il semble fonctionné à quelques petites choses près.

  13. #13
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 679
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 679
    Par défaut
    Citation Envoyé par Marcopololo Voir le message
    comment récupéré les infos de str2 pour les afficher dans ma boite de dialogue.
    Il faudrait en faire quelque chose plutôt que se contenter de le calculer pour rien.

    Citation Envoyé par Marcopololo Voir le message
    Bon le code n'est peut être pas très beau mais il semble fonctionné à quelques petites choses près.
    Il est surtout incohérent: ligne 17, ça fabrique la chaine de caractères to_str à partir d'une liste pour refabriquer la liste de départ à la ligne 23.
    En python on pourrait simplifier tout çà en 2 lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def build_travaux_dates(e):
        # fields = fields.strftime("%d/%m/%Y")
        fields = [
            'parcelles_Travaux_Date1',
            ....
            'parcelles_Travaux_Date6',
            'parcelles_Travaux_Travaux6'
        ]
        items = [e[field] for field in fields if e[field]]
        str2 = '\n'.join(f'{a} : {b}' for a, b in list(batched(items, 2)))
        ....
    batched étant un itérateur du module itertools présent depuis 3.12.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  14. #14
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 284
    Par défaut
    Citation Envoyé par Marcopololo Voir le message
    Bon le code n'est peut être pas très beau mais il semble fonctionné à quelques petites choses près.
    Le but est de faire fonctionnel et si possible le plus simple possible (pour évolutions et maintenance)
    "semble fonctionner" n'est certainement pas un bon critère en codage, voir même c'est plus proche de "poubelle"!

    Une bonne idée d'avoir ces 6 champs dans "e" ? Pour moi, cela ressemble à une très mauvaise conception de la base de donnée ... si pas le cas :

    fields ... c'est un code exemple j'espère, sinon je ne comprends rien à ce code ...
    - Pourquoi ces préfix dans le tableau ??? autant les ajouter (après) à la requete
    - Pourquoi faire 36 manipulations ? Ce n'est pas que fields à une mauvaise structure ? Pourquoi avoir créé cette structure si elle ne correspond pas a notre besoin
    - Quel est le réel but ?
    Si c'est avoir les 6 premiers ou derniers travaux ??? Mais alors pourquoi ne pas simplement faire une bouche (de 1 à 6) au lieux de créer un tableau immonde de constantes.

    -------
    Et reste aussi la question : pourquoi ne pas avoir fait une simple requête sql ?
    $moi= (:nono: !== :oops:) ? :king: : :triste: ;

  15. #15
    Membre éclairé Avatar de Marcopololo
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 311
    Par défaut
    Bonjour,

    Je vais essayé de répondre à toutes ces interrogations.

    Concernant le code je débute et donc je tâtonne et je d"couvre tout ce qui est possible de faire.
    Pour la structure, il s'agit d'un plugin pour QGIS. Actuellement je fonctionne avec des tableaux excel et des jointures pour récupérer les données et j'avais envie de m’affranchir de ces tableaux.
    Dans QGIS on a une table d'attributs par couche et pour l'instant j'essaye de comprendre comment gérer l'interface avec cette table et des champs existants qui proviennent de mes jointures, mais effectivement l'idée serait d'avoir une fonction de configuration qui créerait tous les champs dans ma table QGIS pour ensuite les traiter.
    Et je me dis que c'est en forgeant que l'on devient forgeron, en profitant des compétences d'expert on avance plus vite. Sachant que derrière il n'y a aucun intérêt financier et qu'à 60 ans j'aime toujours autant apprendre, cela me plait.
    Quant à la structure elle provient de ce que j'ai fait en html dans une infobulles avec les limites de QGIS, c'est à dire une couche = une table et donc une ligne par numéro de parcelle, donc limitation du nombre de lignes travaux, idem pour traitement et prévisions.


    J'espère que cela vous permet de comprendre ma démarche. En tout cas merci de votre aide et du temps passé à m'orienter. Vos remarques ne feront que me faire progresser.

  16. #16
    Membre éclairé Avatar de Marcopololo
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 311
    Par défaut
    En tout cas merci cela fonctionne comme je le souhaitais.
    Je vais continuer à lire et à avancer

  17. #17
    Membre éclairé Avatar de Marcopololo
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 311
    Par défaut cas particulier
    J'ai parlé un peu trop vite, je suis tombé sur un cas particulier dans une autre sélection.
    En effet dans certains cas dans le code en dessous on peut avoir le champ parcelles_Travaux_Date1 qui existe mais pas le champ parcelles_Travaux_Remarque1 alors que les champ parcelles_Travaux_Date2 et parcelles_Travaux_Remarque2 existent. Cela provoque une erreur dans la fonction batched puisque il ne trouve pas b dans la ligne 1 alors que a existe.
    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
                def build_travaux_remarques(e):
                    fields = [
                        'parcelles_Travaux_Date1','parcelles_Travaux_Remarque1',
                        'parcelles_Travaux_Date2','parcelles_Travaux_Remarque2',
                        'parcelles_Travaux_Date3','parcelles_Travaux_Remarque3',
                        'parcelles_Travaux_Date4','parcelles_Travaux_Remarque4',
                        'parcelles_Travaux_Date5','parcelles_Travaux_Remarque5',
                        'parcelles_Travaux_Date6','parcelles_Travaux_Remarque6'
                    ]
                    items2 = [e[field] for field in fields if e[field]]
                    str3 = '\n'.join(f'{a} : {b}' for a, b in list(batched(items2, 2)))
                    if not str3:
                        return '...'
                    return str3
                self.dlg.travauxRq.setText(build_travaux_remarques(e))

  18. #18
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 284
    Par défaut
    Tu ne lis toujours pas la doc (si ca fonctionne pourquoi perdre du temps à comprendre ...)

    Existe 36 façons de contourner ton problème, c'est a toi d'essayer

    - build_travaux_remarques(e.attributeMap()) # avec des e.get a l'intérieur
    - for i in range(1,7): key = f"parcelle{i}" ... key = f"remarque{i}" ; if key in ...
    - def get_valeur(e, key): try except ... [ getvaleur(e, field]) for field in fields...
    - [e[field] for field in fields if field in e.fields()] # a adapter/modifier
    - ...

    ------------
    Et comme déjà écrit, ton tableau de constantes est une horreur (mais cela ne te dérange pas ),
    un exemple de remplacement (si tableau est véritablement utile...)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    KEYS = "parcelle", "remarque"
    champs = ("parcelle2", "parcelle4", "parcelle8")  # e.fields()
    keys = [(f"{KEYS[0]}{k}", f"{KEYS[1]}{k}") for k in range(1, 12) if f"{KEYS[0]}{k}" in champs]
    print(keys)
    et ici, la fonction va être ok avec une ou 12 parcelles
    $moi= (:nono: !== :oops:) ? :king: : :triste: ;

  19. #19
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 679
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 679
    Par défaut
    Citation Envoyé par Marcopololo Voir le message
    Cela provoque une erreur dans la fonction batched puisque il ne trouve pas b dans la ligne 1 alors que a existe.
    En supposant que batched retourne l'erreur: "ValueError: not enough values to unpack...", on peut se retrouver avec un nombre "impair" d'items difficiles à regrouper par 2.
    La même structure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        items2 = [e[field] for field in fields if e[field]]
        str3 = '\n'.join(f'{a} : {b}' for a, b in list(batched(items2, 2)))
    peut être "compactée" en:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        str3 = '\n'.join(f'{e[a]} : {e[b]}' for a, b in batched(fields, 2) if e[b])
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  20. #20
    Membre éclairé Avatar de Marcopololo
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 311
    Par défaut
    Oui j'ai bien conscience que mon tableau de constante n'est pas terrible. Il s'agit de nom provenant de jointures entre tableau Excel et Qgis, donc tant que je fais que de l'affichage je suis un peu obligé de conserver les noms. Et le nombre est aussi figé car dans la table attributaire je n'ai qu'une seule ligne par parcelle, et dans le cas de travaux je me suis limité à 6x (date, intitulé et éventuellement remarque).
    Ma maîtrise est celle d'un débutant alors je vois que je ne maîtrise pas les interactions entre une fonction, comme batch et le fait de remettre une condition de contrôle d'erreur de type except. Alors à chaque fois que vous me donnez une info j'essaie de comprendre et de tester, mais pas toujours facile.
    J'ai bien compris que except va éviter l'erreur, reste alors pour moi à intégrer le contrôle de a et b, avec la variable k de a et b, si j'ai bien compris

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Utiliser AVG pour un calcul sur une liste d'entité
    Par VirgApps dans le forum Langage SQL
    Réponses: 3
    Dernier message: 01/10/2014, 14h46
  2. Utiliser le double clic sur une liste dans HTA
    Par papyxy dans le forum VBScript
    Réponses: 3
    Dernier message: 06/07/2014, 09h14
  3. Utiliser LEFT JOIN sur une grosse base de données
    Par bractar dans le forum Requêtes
    Réponses: 20
    Dernier message: 11/01/2014, 07h32
  4. Réponses: 2
    Dernier message: 08/09/2011, 09h07
  5. Réponses: 7
    Dernier message: 18/04/2006, 17h44

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