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 :

Imposer une majuscule dans une chaîne de caractère après un tiret (-)


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Femme Profil pro
    Cartographe
    Inscrit en
    Octobre 2022
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Cartographe
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2022
    Messages : 3
    Par défaut Imposer une majuscule dans une chaîne de caractère après un tiret (-)
    Bonjour à tous,

    Je suis cartographe, je réalise des cartes d'un département qui affichent des noms de ville, de quartier etc. Ces noms sont dans une base de données, ils sont en minuscule. Je souhaite à travers un code python, obtenir des majuscules à chaque début de mot même devant les mots ayant un "-" ex : Saint-Christophe. Le code que j'ai réussi à récupérer et à adapter exclut les articles des noms (de, aux, des, en etc.) et met bien les majuscules en début de mots, mais cela pose problème lorsqu'il y a tiret à un nom propre, il n'en met pas. Est il possible d'intégrer dans ce code une fonction pour obliger les majuscules dans un mot après un tiret ?
    info :
    [graphie] = le champs de mes noms

    Je vous remercie par avance, voila le code actuel :

    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
    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", "aux"}
                )
            ) else w
            for (i, w) in enumerate(s.split())
        )
     
        print(f"{s} --> {FindLabel(s)}")

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Bonjour
    J'aime bien ton code (surtout ce découpage ligne par ligne d'une instruction complexe). Mais il y a quelques incohérences qui font que je le comprends mal. C'est pas grave, on est là pour discuter et aplanir les difficultés

    Déjà def FindLabel([graphie]) ça ça ne marche pas. La syntaxe n'est pas bonne. Soit la fonction reçoit un tableau que tu veux nommer "graphie" et tu écris def FindLabel(graphie), soit elle reçoit n noms à suivre et tu écris def FindLabel(*graphie) (ou plus conventionnellement def FindLabel(*args)). Mais cette notation de tableau en paramètre n'est pas correcte.

    Ensuite le s=[graphie] là aussi me parait bancal. Si "graphie" est déjà un tableau de noms, mettre ce tableau dans un tableau donnera un tableau 2D. Or la 2° dimension me parait peu utile dans ce contexte.

    Et ensuite tu utilises split sur "s" qui est un tableau (enfin une liste). Or une liste ne possède pas de méthode "split". C'est dommage que tu n'aies pas donné un exemple d'appel.

    Bref il faudrait préciser si la fonction reçoit un nom, ou une liste de noms. Perso je préconise l'atomicité (travailler sur "un" élément, quitte à répéter ensuite l'action sur "tous" les éléments).

    Et pour ton principal souci, je le pensais au début pas très compliqué (je pensais à couper sur l'espace plus le tiret via la fonction split() du module "re") mais le souci, c'est qu'au final les tirets disparaissent (le " ".join(...) positionne des espaces uniquement).
    Donc j'ai pondu un petit truc basé sur l'algo suivant
    • récupérer toute la liste des mots du nom
    • si le mot n'est pas un mot interdit, alors remplacer, dans le nom, le mot par le mot transformé

    Accessoirement, puisqu'il semble que le premier mot soit toujours transformé quoi qu'il arrive, autant ne pas en tenir compte et capitaliser la string finale, ça revient au même et ça évite de tester "i != 0" bien inutilement dans 99% des cas. Et puis bon, recréer la liste de mots interdits à chaque itération de la boucle...

    De fait...
    Code python : 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
    import re
     
    def FindLabel(s):
    	bad={
    		"de", "du", "en",
    		"le", "la", "les",
    		"un", "une", "des",
    		"sur", "sous", "aux",
    	}
    	for m in re.split("[- ]", s)[1:]:
    		if m in bad: continue
    		while (f:=s.find(m)) != -1: s=s[0:f] + s[f].upper() + s[f+1:]
    	# for
    	# return s.capitalize()		# Cette solution ne fonctionne pas (voir post de Hominidé ci-dessous)
    	return s[0].upper() + s[1:]	# Cette solution permet de régler le souci
    # FindLabel()
     
    print(FindLabel("xxx, de yyy"))
    print(FindLabel("xxx-yyy"))
    print(FindLabel("xxx-yyy-xxx"))
    print(FindLabel("xxx-yyy-xxx-yyy"))
    print(FindLabel("xxx-de-yyy"))
    print(FindLabel("xxx de-yyy"))
    print(FindLabel("xxx-de yyy"))
    print(FindLabel("en-xxx yyy"))
    print(FindLabel("saint-just-en-chaussée"))

    Pas super optimisé (je pense qu'un pro des regex pourrait améliorer l'idée) mais bon... c'est efficace (et puis vendredi soir=crevé)

    PS: dans ton code d'origine, les parenthèses au "or" n'étaient pas utiles. Cours de mathématiques niveau 6°: les parenthèses servent à prioriser des opérations par rapport à d'autres. On peut écrire (2+3)*4 pour prioriser l'addition sur la multiplication. Mais ça suppose au minimum d'avoir deux opérations. Et dans w not in ... il n'y a qu'une seule opération.
    Les parenthèses aussi sont des instructions Python, donc elles aussi ne se mettent que quand c'est nécessaire (ou quand cela facilite la lecture, je ne dirai rien si tu écris if (a+b) == c même si c'est là aussi inutile de par les priorités naturelles du langage).

    [edit] Suite à la remarque de Hominidé, j'ai rectifié mon code en mettant en commentaire l'erreur qu'il a relevée
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre Expert
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 923
    Billets dans le blog
    8
    Par défaut
    Bonjour,
    Citation Envoyé par Sve@r
    Accessoirement, puisqu'il semble que le premier mot soit toujours transformé quoi qu'il arrive, autant ne pas en tenir compte et capitaliser la string finale, ça revient au même et ça évite de tester "i != 0" bien inutilement dans 99% des cas.
    Il y a de l'idée, mais plouf:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> 'le Pingre A Oublié, une Fois Encore, Son Porte-Monnaie'.capitalize()
    'Le pingre a oublié, une fois encore, son porte-monnaie'
    >>>
    Tu peux constater que ce n'est pas juste la première lettre qui est mise en majuscule, mais que c'est l'ensemble de la string qui est transformée. (C'est ce qui se passe avec le code que tu as présenté)

    Sinon sans re:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def FindLabel(s):
        out = str()
        bad={"de", "du", "en","le", "la", "les",
             "un", "une", "des","sur", "sous", "aux",
    	}
        for index, label in enumerate(s.split(" ")):
            if label in bad and index:
                out += label + " "
            elif "-" in label:
                out += "-".join(word.capitalize() for word in label.split('-'))
            else:
                out += label.capitalize() + " "
        return out
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> FindLabel("le pingre a oublié, une fois encore, son porte-monnaie")
    'Le Pingre A Oublié, une Fois Encore, Son Porte-Monnaie'
    >>>

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Hominidé Voir le message
    Il y a de l'idée, mais plouf:
    Tu peux constater que ce n'est pas juste la première lettre qui est mise en majuscule, mais que c'est l'ensemble de la string qui est transformée. (C'est ce qui se passe avec le code que tu as présenté)
    Zut !!!
    En plus j'avais au départ codé correctement le truc (en prenant tous les mots et en testant i != 0) puis je l'ai modifié à la fin sans vérifier !!! Effectivement capitalize() change tous les mots d'une chaine et non pas son premier caratère, je viens de l'apprendre
    Enfin ça s'arrange facilement. Suffit de remplacer return s.capitalize() par return s[0].upper() + s[1:]

    Citation Envoyé par Hominidé Voir le message
    Sinon sans re:
    Bah pourquoi faire? "re" c'est bien pratique. Si demain il faut aussi gérer le "_", on le rajoute dans re.split("[- _]", s) et hop, c'est réglé
    Et puis le PO l'avait importé donc je me suis dit "ok, il a probablement raison, autant que ça serve"...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre Expert
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 923
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par Sve@r
    Bah pourquoi faire?
    histoire de blablater devant un café

  6. #6
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    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 062
    Par défaut
    Hello,

    Voici ma solution,

    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 find_label(s):
        words = s.split()
        words_transformed = [words[0].capitalize()]
        bad = {
            "de", "du", "en", "le", "la", "les",
            "un", "une", "des", "sur", "sous", "aux"
        }
        for word in words[1:]:
            if word in bad:
                ws = word
            else:
                ws = '-'.join(map(str.capitalize, word.split("-")))
            words_transformed.append(ws)
        return ' '.join(words_transformed)
    ou mieux,

    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
    BAD = {    
        "de", "du", "en", "le", "la", "les",
        "un", "une", "des", "sur", "sous", "aux"
    }
     
     
    def find_label(s):
        words = s.split()
        words_transformed = [words[0].capitalize()]
        for word in words[1:]:
            if word in BAD:
                ws = word
            else:
                ws = '-'.join(map(str.capitalize, word.split("-")))
            words_transformed.append(ws)
        return ' '.join(words_transformed)

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Voici ma solution,
    Suis désolé, aucune des deux ne fonctionne pour "xxx-yyy". Elles retournent "Xxx-yyy" alors que ça devrait retourner "Xxx-Yyy". C'est parce que "words" a splitté "s" sur l'espace mais "s" ne contient pas d'espace. Et comme la boucle commence à l'élément [1] qui donc n'existe pas...

    PS: au fait, ma solution non plus ne fonctionne pas parfaitement. Pour "xxx-yyy-x" elle retourne "XXX-Yyy-X". C'est parce que j'utilise find() pour repérer la position de la chaine à transformer et bon ben find("X") quand il y a "XXX"...
    Après bon je me dis que pour des noms de lieux, le cas doit être peu probable (balance classique "probabilité de souci" vs "coût de développement pour y remédier")

    Citation Envoyé par fred1599 Voir le message
    ou mieux,
    Mieux de passer par une globale?
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    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 062
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Suis désolé, aucune des deux ne fonctionne pour "xxx-yyy". Elles retournent "Xxx-yyy" alors que ça devrait retourner "Xxx-Yyy". C'est parce que "words" a splitté "s" sur l'espace mais "s" ne contient pas d'espace. Et comme la boucle commence à l'élément [1] qui donc n'existe pas...

    Mieux de passer par une globale?
    Peux-tu me donner un exemple, car l'exemple donné par @Hominidé fonctionne chez moi ?

    Pour la variable globale oui dans le sens où à chaque appel de fonction, tu ne demandes pas à reconstruire bad.

    Parce-que si c'est ce que je comprend (mot composé en tout début de phrase) alors on peut imaginer 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
    BAD = {    
        "de", "du", "en", "le", "la", "les",
        "un", "une", "des", "sur", "sous", "aux"
    }
     
     
    capitalize = lambda w: '-'.join(map(str.capitalize, w.split("-")))
     
     
    def find_label(s):
        words = s.split()
        words_transformed = [capitalize(words[0])]
        for word in words[1:]:
            if word in BAD:
                ws = word
            else:
                ws = capitalize(word)
            words_transformed.append(ws)
        return ' '.join(words_transformed)

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Peux-tu me donner un exemple, car l'exemple donné par @Hominidé fonctionne chez moi ?
    Alors bon c'est d'après ce que j'ai compris, un nom comme "saint-just de la chaussée" doit devenir "Saint-Just de la Chaussée". C'est à dire que tous les mots qui ne sont pas interdits sont alors capitalisés tout en préservant le séparateur d'origine (avec aussi le premier mot capitalisé quel qu'il soit même si mot interdit)

    Citation Envoyé par fred1599 Voir le message
    Pour la variable globale oui dans le sens où à chaque appel de fonction, tu ne demandes pas à reconstruire bad.
    Compris. Mais j'aime pas. C'est plus fort que moi, je n'aime pas utiliser les globales. J'aime trop la notion d'indépendance de fonction (on prend une fonction, on la met dans n'importe quel code elle continue à remplir son job).
    A la limite, ce que je te proposerais pour l'éviter serait un truc ressemblant à ceci
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def FindLabel(*tabMot):
    	def __work(mot):
    		...
    		return (le mot comme il faut)
    	# __work()
     
    	bad={...}
    	yield from map(__work, tabMot)
    # FindLabel()
     
    for x in FindLabel("...", "...", "...", "..."): print(x)
    Ainsi, un seul appel pour n mots et donc une seule définition de "bad" sans passer par une globale. Un petit ersatz d'objet en quelque sorte. Evidemment si tu dois l'utiliser à différents moments de ton code il te faudra l'appeler plusieurs fois(et là ça redéfinira à chaque appel et le bad et la sous-fonction) mais je pense que c'est quand-même un compromis qui pourrait satisfaire la grande majorité des cas.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  10. #10
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    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 062
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ainsi, un seul appel pour n mots et donc une seule définition de "bad" sans passer par une globale. Un petit ersatz d'objet en quelque sorte. Evidemment si tu dois l'utiliser à différents moments de ton code il te faudra l'appeler plusieurs fois(et là ça redéfinira à chaque appel et le bad et la sous-fonction) mais je pense que c'est quand-même un compromis qui pourrait satisfaire la grande majorité des cas.
    Ok, et si j'ai besoin de réutiliser les mots clé se trouvant dans la variable bad dans une autre fonction du projet ?

    Citation Envoyé par Sve@r Voir le message
    Alors bon c'est d'après ce que j'ai compris, un nom comme "saint-just de la chaussée" doit devenir "Saint-Just de la Chaussée". C'est à dire que tous les mots qui ne sont pas interdits sont alors capitalisés tout en préservant le séparateur d'origine (avec aussi le premier mot capitalisé quel qu'il soit même si mot interdit)


    Oui mais je ne connais pas tous les cas possibles, et c'est tout l'intérêt des tests unitaires, on part d'une base et on vérifie à chaque nouveau cas non fonctionnel que tout passe comme on veut.

  11. #11
    Invité
    Invité(e)
    Par défaut
    @fred1599
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    find_label('Le Moulin de lévêque')
    'Le Moulin de Lévêque'
     
    find_label('Le Moulin de-lévêque')
    'Le Moulin De-Lévêque'
    Je ne sais pas si ce genre d'exemple existe dans la vraie vie... Par contre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    find_label('ducey-les-chéris')
    'Ducey-les-chéris'
    Pas bon non plus

  12. #12
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    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 062
    Par défaut
    Dernier tests, finalement c'est au PO de faire 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
    BAD = {    
        "de", "du", "en", "le", "la", "les",
        "un", "une", "des", "sur", "sous", "aux"
    }
     
     
    def capitalize(w): return '-'.join(
        (wd.capitalize() if (
            (wd in BAD and not i) or wd not in BAD) else wd for i,
            wd in enumerate(
                w.split('-'))))
     
     
    def find_label(s):
        words = s.split()
        words_transformed = [capitalize(words[0])]
        for word in words[1:]:
            ws = capitalize(word) if word not in BAD else word
            words_transformed.append(ws)
        return ' '.join(words_transformed)
    Sve@r

    Dans ma vision des choses, je passe alors "bad" (qui se trouvera non pas en globale mais dans la fonction main()) en paramètre à toutes les fonctions qui en ont besoin.
    Oui c'est une variable globale dans le namespace de ta fonction main à ton module ... étant donné que cette fonction est la seule exécutée à l'ensemble du projet. Du coup tu t'imposes un paramètre de fonction pour chaque fonction en ayant besoin, alors que l'on pourrait très bien importer d'un module constants.py l'ensemble des constantes du projet par exemple.

    "config" contient la configuration, "envp" l'environnement et "bdd" le module d'accès à la bdd. Avec ça, je couvre tous les champs possibles
    Oui mais je vois pas le lien avec notre cas, on parle juste d'une constante, toi tu parles de configuration qui a mon sens est liée à des constantes cachées de ta base de données et ton environnement. C'est un fichier qu'on ne présente pas dans un code, alors que des constantes comme BAD ne doivent pas être cachées.

    Perso j'utilise des variables d'environnement que j'appelle avec dotenv, mais ce choix est vraiment perso.

  13. #13
    Candidat au Club
    Femme Profil pro
    Cartographe
    Inscrit en
    Octobre 2022
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Cartographe
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2022
    Messages : 3
    Par défaut
    Bonjour,

    D'abord merci beaucoup à tous pour votre aide, je ne m'attendais pas à ce qu'il y ait autant de discussion pas rapport à ce sujet !
    Pour répondre à Sve@r
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    def FindLabel([graphie])
    est une expression automatiquement générée par mon logiciel de cartographie, nous sommes obligés de l'utiliser et [graphie] correspond au champs d'une table, notre logiciel utilise cet affichage en crochet, si j'utilises des parenthèses il considère qu'il y a une erreur, je ne sais pas pourquoi...

    Je n'ai pas un niveau aussi avancé que les vôtres, donc je ne suis pas sure que j'arriverai à répondre à toutes les subtilités de vos codes, mais j'ai néanmoins réussi à appliquer le premier code d'Hominidé (un peu plus user friendly pour les débutantes comme moi...! ). Mes étiquettes excluent bien la liste des articles tout en forçant la majuscule après le "-".

    Est-il possible d'intégrer une liste qui va forcer la majuscule après d'autres éléments (par ex: l' , d', - etc.) ? Au début j'ai notamment essayé d'ajouter un "elif" en plus, en me basant sur celui qui a été crée pour le "-" en le remplaçant par "d'", mais ça n'a pas fonctionné. Je me suis dit ensuite pourquoi pas faire une liste (maj), c'est peut être plus simple que d'ajouter des "elif" à chaque fois mais là encore j'ai un problème d'expression... Ce que j'ai essayé de faire :

    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 FindLabel(s):
        out = str()
        bad={"de", "du", "en","le", "la", "les",
             "un", "une", "des","sur", "sous", "aux",
        }
        maj={"-", "d'", "l'"}
        for index, label in enumerate(s.split(" ")):
            if label in bad and index:
                out += label + " "
            elif maj in label:
                out += "-".join(word.capitalize() for word in label.split(maj))
            else:
                out += label.capitalize() + " "
        return out

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Karybu Voir le message
    Pour répondre à Sve@r
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    def FindLabel([graphie])
    est une expression automatiquement générée par mon logiciel de cartographie, nous sommes obligés de l'utiliser et [graphie] correspond au champs d'une table, notre logiciel utilise cet affichage en crochet, si j'utilises des parenthèses il considère qu'il y a une erreur, je ne sais pas pourquoi...
    Alors ce n'est pas du Python !!!
    Nom : VirtualBox_Xubuntu64_10_10_2022_17_45_02.png
Affichages : 529
Taille : 175,7 Ko

    C'est peut-être du "python spécifique logiciel carto" (au fait c'est quoi ce logiciel? QGis? Car QGis a été écrit en python) mais si ce "python spécial" a une syntaxe qui n'est pas la syntaxe de base, on aura du mal...

    Citation Envoyé par Karybu Voir le message
    Est-il possible d'intégrer une liste qui va forcer la majuscule après d'autres éléments (par ex: l' , d', - etc.) ?
    Bien entendu. Mon script n'est peut-être pas user friendly mais justement j'ai expliqué son principe. La seule ligne "un peu" complexe est celle-ci: while (f:=s.find(m)) != -1: s=s[0:f] + s[f].upper() + s[f+1:] et qui se lit "tant que je trouve le mot m dans s à une position f alors je récupère intact tout ce qui se trouve avant f, j'y rajoute la lettre de la position f mise en majuscule et je récupère intact tout ce qui se trouve après f" ce qui en fait, ne fait que mettre la première lettre du mot "m" en majuscule a l'endroit où se trouve cette lettre. Et dans une boucle au cas où il y aurait plusieurs fois le mots.
    Elle fait appel à un nouvel opérateur, le ":=" (arrivé avec Python 3.8) et qui permet d'affecter tout en gardant la valeur en "main" pour ensuite la tester (donc la valeur du find() va dans "f" mais est aussi testée sur -1).
    Sans cet opérateur, le truc s'écrivait alors ainsi...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while True:
    	f=s.find(m)
    	if f == 1: break
    	s=s[0:f] + s[f].upper() + s[f+1:]
    # while
    ... ce qui est probablement plus user friendly.

    Mais surtout je l'avais prévu pour le cas quasi certain (tellement courant ici) du "ah au fait j'ai oublié que..."
    Code python : 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
    import re
     
    def FindLabel(s):
    	bad={
    		"de", "du", "en",
    		"le", "la", "les", "l",
    		"un", "une", "des", "d",
    		"sur", "sous", "aux",
    	}
    	for m in re.split("[-' ]", s)[1:]:
    		if m in bad: continue
    		while (f:=s.find(m)) != -1: s=s[0:f] + s[f].upper() + s[f+1:]
    	# for
    	return s[0].upper() + s[1:]
    # FindLabel()
     
    print(FindLabel("xxx d'argentière"))
    print(FindLabel("xxx de-l'argentière"))

    Et si tu regardes bien les différences avec le précédent, elles sont
    1. dans la liste des mots interdits, qui s'est vue rajouter "l", "d"
    2. dans la liste des éléments de séparation, qui est passée de "- " (tiret ou espace) à "-' " (tiret ou apostrophe ou espace)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Membre éprouvé
    Homme Profil pro
    Vagabong étudiant en annalyse du signal.
    Inscrit en
    Avril 2019
    Messages
    130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Vagabong étudiant en annalyse du signal.
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2019
    Messages : 130
    Par défaut c'est déja implémenté
    Salut,

    Dans les versions récentes de python, la méthode title des chaînes de caractère fait ce boulot là:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    >>> "Les gens arc-en-ciel sont d'argentière".title()
    "Les Gens Arc-En-Ciel Sont D'Argentière"
    Voila! mais c'est intéressant pour l'exercice de se poser la question

  16. #16
    Membre Expert
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 923
    Billets dans le blog
    8
    Par défaut
    Bonjour,
    Citation Envoyé par robinechuca Voir le message
    Salut,

    Dans les versions récentes de python, la méthode title des chaînes de caractère fait ce boulot là:
    Bien vu .
    Avec la gestion des exclusions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    def FindLabel(s):
    	bad={
    		"de", "du", "en",
    		"le", "la", "les", "l",
    		"un", "une", "des", "d",
    		"sur", "sous", "aux",
    	}
    	mots = s.title().split()
    	return " ".join(mot if mot.lower() not in bad
                             else mot.lower() for mot in mots)

Discussions similaires

  1. Réponses: 3
    Dernier message: 19/08/2014, 13h14
  2. [MySQL] Remplacer une chaîne de caractères dans une base de données
    Par Furius dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 27/11/2013, 21h06
  3. Réponses: 3
    Dernier message: 20/05/2008, 13h54
  4. Réponses: 4
    Dernier message: 23/06/2004, 09h51
  5. Réponses: 3
    Dernier message: 09/05/2002, 01h39

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