Etiquettes en cartographie avec Python

Résolu/Fermé
Karybu Messages postés 2 Date d'inscription mardi 6 septembre 2022 Statut Membre Dernière intervention 6 septembre 2022 - Modifié le 6 sept. 2022 à 12:41
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 - 7 sept. 2022 à 13:12

Bonjour,

Débutante actuellement en Python, je suis cartographe et je souhaite avoir des noms de quartier / résidence. Je passe par le biais de Python pour les structurer. Les noms de quartiers sont de bases en minuscule. Mon objectif est d'avoir des étiquettes avec la première lettre de chaque mot tout en majuscule sauf les articles en milieu de phrase uniquement.

Exemple : "la résidence les cerisaies" -> "La Résidence les Cerisaies"

J'ai établi un code qui me permet de réduire en minuscule certains articles, mais je me rends compte qu'il impacte également les articles placés en début de phrase qui ne sont plus en majuscule, j'obtiens ainsi "la Résidence les Ceriseraies". J'ai essayé d'ajouter la fonction .capitalize() a plusieurs endroits de mon code mais rien n'y fait... Est ce que quelqu'un aurait une idée ? Je vous remercie par avance ! 

Voici mon code : 

def FindLabel ( [graphie] ):
    lower_case = ["de", "des", "en", "du", "le", "la", "les", "l'"]
    output_string = ""
    input_list= [graphie].split(" ")
    for word in input_list:
        if word in lower_case:
            output_string += word + " "
        else:
            temp = word.title()
            output_string += temp + " "
    return output_string


Windows / Chrome 104.0.0.0

A voir également:

3 réponses

mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
6 sept. 2022 à 13:02

Bonjour,

Voici le code que je te propose, qui intègre la suggestion de yg_be.

Code :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re

def capitalize_place(s):
    return " ".join(
        w.capitalize() if (     
            i == 0              
            or (
                w not in {"de", "des", "en", "du", "le", "la", "les", "sur", "sous", "en"}
                and not w.startswith("l'")
            )
        ) else w
        for (i, w) in enumerate(s.split())
    )

for s in (
    "la résidence les cerisaies",
    "le château de l'île",      
    "paris",
    "issy les moulineaux",
    "la ferté sous jouarre"
):
    print(f"{s} --> {capitalize_place(s)}")

Résultat :

la résidence les cerisaies --> La Résidence les Cerisaies
le château de l'île --> Le Château de l'île
paris --> Paris
issy les moulineaux --> Issy les Moulineaux
la ferté sous jouarre --> La Ferté sous Jouarre

Explications :

  • enumerate permet d'itérer sur chaque mot de s. Le mot courant est w et est indexé par i (à partir de 0)
  • on met le mot en capital si
    • c'est le premier mot (i == 0)
    • ou si c'est un mot qui n'est pas un article ou une préposition, et que ce n'est pas un mot qui commence par l'.
  • la méthode join s'applique à une chaîne (ici " ") et prend en paramètre une séquence de chaînes de caractères (les mots éventuellement corrigés) et les relie avec la chaîne à laquelle join s'applique (donc ici " "). Dit autrement, étant donnée une liste de mots, " ".join(mots) retourne la chaîne de caractère qui contient les mots séparés d'une espace.
  • ici ce qu'on appelle mots n'est pas une liste (on pourrait, mais ça n'est pas utile), mais un itérateur. C'est suffisant pour join.

Bonne chance

2
Karybu Messages postés 2 Date d'inscription mardi 6 septembre 2022 Statut Membre Dernière intervention 6 septembre 2022 1
6 sept. 2022 à 15:39

Merci beaucoup à vous deux, avec quelques modifs pour l'adapter à mon logiciel et avec votre code ça a fonctionné ! 

Du coup, pour ceux qui utilisent les logiciels de SIG/cartographie, [graphie] correspond au champ dans lequel se trouve les étiquettes à modifier donc selon le nom de votre champs, voilà le code que j'ai utilisé (il faut bien mettre la fonction FindLabel) : 

import re

def FindLabel([graphie]):
    s = [graphie]
    return " ".join(
        w.capitalize() if (     
            i == 0              
            or (
                w not in {"de", "des", "en", "du", "le", "la", "les", "sur", "sous", "en"}
                and not w.startswith("l'")
            )
        ) else w
        for (i, w) in enumerate(s.split())
    )

    print(f"{s} --> {FindLabel(s)}")
1
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
7 sept. 2022 à 13:12

Merci pour ce complément d'informations, bonne continuation :-)

0
yg_be Messages postés 22730 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
6 sept. 2022 à 12:29

bonjour,

Ne suffit-il pas, en ligne 6, de tester si c'est le premier mot?

0