Skip to content

Instantly share code, notes, and snippets.

@rg3915
Last active March 28, 2024 11:52
Show Gist options
  • Save rg3915/a6a4bdfd7e0a2f69cc9d to your computer and use it in GitHub Desktop.
Save rg3915/a6a4bdfd7e0a2f69cc9d to your computer and use it in GitHub Desktop.
Colocar a primeira letra de cada palavra em maiúsculo, exceto em preposições 'da', 'de', 'di', 'do', 'du', 'para' ... - nome - pyladies - python

Tratar nomes com preposições

PyLadiesSP

Objetivo: colocar a primeira letra de cada palavra em maiúsculo, exceto em preposições 'da', 'de', 'di', 'do', 'du', 'para' ...

Texto: minicurso de python para mulheres

Resultado esperado: Minicurso de Python para Mulheres

Note que o de e para não estão em maiúsculo.

versão 1

name='minicurso de python para mulheres'
p = ['da', 'de', 'di', 'do', 'du', 'para'] # preposição

items = []
for item in name.split():
    if not item in p:
        item = item.capitalize()
    items.append(item)

new_name = ' '.join(items)

Explicação

Vamos criar uma variável de texto.

name='minicurso de python para mulheres'

Definimos uma lista de preposições.

p = ['da', 'de', 'di', 'do', 'du', 'para'] # preposição

Vamos definir uma nova lista vazia ...

items = []

... nesta lista vazia iremos adicionar novos valores com o comando append().

O comando a seguir faz um laço percorrendo a lista name.split(), isso mesmo, name.split() transforma nosso name inicial numa lista, veja:

>>> name.split()
['minicurso', 'de', 'python', 'para', 'mulheres']

Bom, então o laço (a seguir) percorre os itens dessa lista, onde item é uma variável que percorre cada elemento da lista...

for item in name.split():
    if not item in p:
        # ...

if not item in p significa "se o item não estiver em p ". Ou seja, se cada item de name.split() não estiver em p então transforma em maiúsculo.

De novo

>>> name.split()
['minicurso', 'de', 'python', 'para', 'mulheres']
  • 'minicurso' está em p?

    • RE: Não. Então será retornado 'Minicurso'.
  • 'de' está em p?

    • RE: Sim. Então ele não será alterado.

item = item.capitalize() é o comando responsável por transformar em maiúsculo.

Veja novamente o trecho de código:

for item in name.split():
    if not item in p:
        item = item.capitalize()
    items.append(item)

Então, temos um laço que pega todos os itens da lista de nomes, verifica se cada item está na lista de preposições, se não estiver então transforma em maiúsculo. E por fim adiciona o item maiúsculo na nova lista chamada items.

Finalmente, com o comando join() nós juntamos os items e colocamos um espaço entre eles.

new_name = ' '.join(items)

Se você estiver usando o modo interativo digite

>>> new_name
'Minicurso de Python para Mulheres'

para ver o resultado final.

versão 2

name='minicurso de python para mulheres'
p = ['da', 'de', 'di', 'do', 'du', 'para']

def cap_name(name):
    items = []
    for item in name.split():
        if not item in p:
            item = item.capitalize()
        items.append(item)
    return ' '.join(items)

cap_name(name)

Explicação

Agora nós temos todo o conteúdo da versão anterior numa função, assim toda vez que você usar a função cap_name() ele irá tratar o texto, vejamos em dois exemplos diferentes:

>>> name1='minicurso de python para mulheres'
>>> name2='sábado, 28 de novembro de 2015'
>>> cap_name(name1)
'Minicurso de Python para Mulheres'
>>> cap_name(name2)
'Sábado, 28 de Novembro de 2015'

versão 3

name='minicurso de python para mulheres'
p = ['da', 'de', 'di', 'do', 'du', 'para']
' '.join(list(map(lambda w: w.capitalize() if not w in p else w, name.split())))

Explicação

Tem gente que adora escrever vários comandos numa linha só. Isso pode ser bom pra economizar linhas de código, mas pode ser ruim por tornar o código ilegível, dependendo da complexidade. Mas deixei este exemplo para ver que no Python isso é possível. Quanto ao seu uso, vai depender da sua escolha ou da pessoa que for ler o seu código. O ideal é que o código seja legível e entendível. Por isso que é bom sempre ler The Zen of Python

>>> import this

Bom, vou começar a explicação de dentro pra fora.

atribuição condicional de valor

if condition:
    x = true_value
else:
    x = false_value

Podemos escrever o if acima numa linha só:

x = true_value if condition else false_value

Ou seja,

<expressão_se_verdadeiro> if condição else <expressão_se_falso>

No nosso exemplo

w.capitalize() if not w in p else w

significa que w será maiúsculo se w não estiver em p, caso contrário, ele simplesmente retorna w, sem fazer nada com ele.

lambda

Pequenas funções anônimas podem ser criadas com a palavra-chave lambda. O lambda serve para criar uma variável que será usada exclusivamente dentro da função criada.

f = lambda x: x**2

A função acima é anônima, pois não foi definido um nome pra ela, porém esta função eleva um número ao quadrado.

>>> f(8)
64
>>> f(10)
100

No nosso caso

lambda w: w.capitalize()

transforma o valor da variável w em maiúsculo.

map

O mapeamento aplica uma função a todos os itens de uma lista, gerando uma nova lista com os resultados.

map(função, sequência)

Mas antes vamos ver o que é range.

range é uma sequência numérica com começo, fim e passo.

range(start, stop[, step])

Exemplo

>>> list(range(1,10,2))
[1, 3, 5, 7, 9]

O list é necessário para receber os valores de range. No nosso exemplo, a lista começa em 1 (incluindo o 1) até 10 (exceto o 10), e o passo é 2. Como resultado final ele retorna todos os números de 1 a 9 pulando de 2 em 2.

Voltando ao exemplo do map, podemos escrever a tabuada do 9 usando o código a seguir

>>> n = range(1,11)
>>> def tabuada_nove(x):
...     return x*9
...
>>> map(tabuada_nove, n)
<map object at 0xb69e86ac>

Opa, ele retornou um objeto? Como ver o resultado deste objeto? Use o list().

>>> list(map(tabuada_nove, n))
[9, 18, 27, 36, 45, 54, 63, 72, 81, 90]

Nossa, já me perdi. Onde estávamos? Ah...

list(map(lambda w: w.capitalize() if not w in p else w, name.split()))

nosso comando maluco de uma linha só. Lembre-se do map.

map(função, sequência)

Então, no nosso comando lambda w: w.capitalize() if not w in p else w é a função.

E name.split() é a sequência.

E com list criamos uma nova lista dada pelo map. Certo?

Finalmente, juntamos todos os items da lista com o comando join() e colocamos um espaço entre eles.

>>> ' '.join(list(map(lambda w: w.capitalize() if not w in p else w, name.split())))
'Minicurso de Python para Mulheres'

Ufa, veja esta animação pra juntar tudo na cachola.

img

versão 4

Baseado em Python Titlecase a String with exceptions

name='minicurso de python para mulheres'
p = ['da', 'de', 'di', 'do', 'du', 'para']
print(' '.join(word if word in p else word.title() for word in name.capitalize().split(' ')))

Bons estudos!

PyLadiesSP

@CoutinhoElias
Copy link

CoutinhoElias commented Feb 23, 2020

Baseado na versão 2 apliquei o lower()
para aumentar a ação do código caso digitador erre colocando DE, De ou dE e adicionei os plurais em "p".

p = ['da','das', 'de', 'di', 'do','dos', 'du', 'para', 'com']

def cap_name(name):
    items = []
    for item in name.split():
        if not item.lower() in p:
            item = item.capitalize()
        else:
            item = item.lower()
        items.append(item)
    return ' '.join(items)

Outro comentário é que tentei mas não consegui fazer o código ficar em formato python mesmo clicando em <> e escrevendo com as identações entre a marcação.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment