[python-brasil] detectar acentuação em string

2,042 views
Skip to first unread message

alexandre

unread,
Jul 29, 2009, 11:03:48 PM7/29/09
to python...@yahoogrupos.com.br
estou fazendo um script para linux onde chamo o programa pdftk através de
subprocess.call().
o pdftk tem problemas com arquivos com caracteres acentuados como este:
química\ geral.pdf.
Gostaria de saber como detectar esses caracteres ilegais nas strings dos
nomes dos arquivos.


--
Alexandre Carneiro


[As partes desta mensagem que não continham texto foram removidas]

------------------------------------

,-----------------------------------------------------------.
| Antes de enviar um e-mail para o grupo leia: |
| http://www.pythonbrasil.com.br/moin.cgi/AntesDePerguntar |
| E se você é usuário do BOL lembre-se de cadastrar o |
| e-mail do grupo na lista branca do seu sistema anti-spam. |
`-----------------------------------------------------------´Links do Yahoo! Grupos

<*> Para visitar o site do seu grupo na web, acesse:
http://br.groups.yahoo.com/group/python-brasil/

<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@yahoogrupos.com.br

<*> O uso que você faz do Yahoo! Grupos está sujeito aos:
http://br.yahoo.com/info/utos.html


Narcélio Filho

unread,
Jul 30, 2009, 2:15:52 AM7/30/09
to python...@yahoogrupos.com.br
> o pdftk tem problemas com arquivos com caracteres acentuados como este:
> química\ geral.pdf.
> Gostaria de saber como detectar esses caracteres ilegais nas strings dos
> nomes dos arquivos.

Esses caracteres não são exatamente "ilegais" não. Qual erro está
dando? Mostre o stacktrace completo aí pra ajudar! De repente seria mais
elegante corrigir o problema exato.


Mas respondendo à sua pergunta... pra saber se algum caractere de uma
string não é ASCII, às 3:15 da madrugada, eu faria assim:

import string

def tem_caractere_ilegal(s):
return any(c not in string.ascii_letters for c in s)


--
[]s, Narcélio

Danilo Cabello

unread,
Jul 30, 2009, 8:45:35 AM7/30/09
to python...@yahoogrupos.com.br
2009/7/30 Luciano Ramalho <ram...@gmail.com>:
> Muito bom exemplo de uso da função any, Narcélio.
>
> Por sinal, pessoal, vale a pena notar as funções embutidas any, all e
> sum que existem no Python há relativamente pouco tempo e permitem um
> estilo de programação funcional bem esperto e legível.
>
> A única coisa que eu não faria igual é o nome da função: eu chamaria
> ela de nao_ascii, para não repetir a idéia de que caracteres
> acentuados são ilegais por algum motivo. Legalize-it!

Realmente o any é bem elegante preciso aprender/acostumar a usar esses
recursos, inicialmente eu faria assim:

try:
str(u"química")
except UnicodeEncodeError:
raise "NON-ASCII" # Sua exception

Luciano Ramalho

unread,
Jul 30, 2009, 6:09:23 AM7/30/09
to python...@yahoogrupos.com.br
2009/7/30 Narcélio Filho <narc...@gmail.com>:

>   Esses caracteres não são exatamente "ilegais" não. Qual erro está
> dando? Mostre o stacktrace completo aí pra ajudar! De repente seria mais
> elegante corrigir o problema exato.

Concordo!

>   Mas respondendo à sua pergunta... pra saber se algum caractere de uma
> string não é ASCII, às 3:15 da madrugada, eu faria assim:
>
> import string
>
> def tem_caractere_ilegal(s):
>     return any(c not in string.ascii_letters for c in s)

Muito bom exemplo de uso da função any, Narcélio.

Por sinal, pessoal, vale a pena notar as funções embutidas any, all e
sum que existem no Python há relativamente pouco tempo e permitem um
estilo de programação funcional bem esperto e legível.

A única coisa que eu não faria igual é o nome da função: eu chamaria
ela de nao_ascii, para não repetir a idéia de que caracteres
acentuados são ilegais por algum motivo. Legalize-it!

[ ]s
Luciano

Nycholas de Oliveira e Oliveira

unread,
Jul 30, 2009, 9:20:23 AM7/30/09
to python...@yahoogrupos.com.br
:)),

Dica, se você quiser ignorar esses caracteres não ascii utilize a
normalize do unicodedata.

>>> from unicodedata import normalize
>>> def nfkd(st):
... return normalize('NFKD',
st.decode('iso-8859-1')).encode('ascii', ''ignore')


--
Até mais e boa sorte,
Nycholas de Oliveira e Oliveira.

Luciano Ramalho

unread,
Jul 30, 2009, 10:35:36 AM7/30/09
to python...@yahoogrupos.com.br
2009/7/30 Danilo Cabello <danilo....@gmail.com>:

> 2009/7/30 Luciano Ramalho <ram...@gmail.com>:
>> Muito bom exemplo de uso da função any, Narcélio.
>>
>> Por sinal, pessoal, vale a pena notar as funções embutidas any, all e
>> sum que existem no Python há relativamente pouco tempo e permitem um
>> estilo de programação funcional bem esperto e legível.
>>
>> A única coisa que eu não faria igual é o nome da função: eu chamaria
>> ela de nao_ascii, para não repetir a idéia de que caracteres
>> acentuados são ilegais por algum motivo. Legalize-it!
>
> Realmente o any é bem elegante preciso aprender/acostumar a usar esses
> recursos, inicialmente eu faria assim:
>
> try:
>        str(u"química")
> except UnicodeEncodeError:
>        raise "NON-ASCII" # Sua exception

Este exemplo tem alguns defeitos, Danilo.

Primeiro, normalmente você vai querer testar uma variável, e não uma
constante, certo, então uma função completa seria assim:

#!/usr/bin/env python
# coding: utf-8

def ascii_puro(s): # codigo errado, não copie sem entender!!!
try:
str(s)
except UnicodeEncodeError:
return False
return True

Só que se você testar assim, vai ter o seguinte resultado:

print ascii_puro('a')
print ascii_puro('á')
print ascii_puro(u'a')
print ascii_puro(u'á')

True
True
True
False

Ou seja, 'á' foi considerado ASCII puro, e não é... O problema é o que
o seu método depende do tipo exato da string, se é str ou unicode, e
ainda depende do encoding default to Python, que no Python 2 é ASCII
mas no 3 é UTF-8, então é uma solução muito frágil. Para fazer
funcionar, fica assim:

#!/usr/bin/env python
# coding: utf-8

def ascii_puro(s):
if type(s) is type(u''):
try:
str(s)
except UnicodeEncodeError:
return False
return True
else:
try:
unicode(s)
except UnicodeDecodeError:
return False
return True

print ascii_puro('a')
print ascii_puro('á')
print ascii_puro(u'a')
print ascii_puro(u'á')

Saída:

True
False
True
False

Mas ainda assim estamos contando com o encoding default, então
realmente contar com estes erros não é o canal. Uma alternativa usando
exceções de forma mais segura seria esta:

def ascii_puro(s):
try:
s.encode('ascii')
except (UnicodeEncodeError, UnicodeDecodeError):
return False
return True

A vantagem aqui é que o encoding 'ascii' está sendo mencionado
explicitamente, o que é importante porque no Python 3 o encoding
padrão deixa de ser ascii e passa a ser UTF-8, então muitos problemas
com acentos que nós temos hoje vão desaparecer, e a solução do Danilo
apresentaria outro problema.

O método encode é implementado em C, então tem alto desempenho, mas
expressões geradoras (como na solução do Narcélio) também tẽm alto
desempenho.

O Ricbit ou o Dorneles podem dar uma solução em 7 caracteres, mas aí
eu não sei se vamos entender ;-).

[ ]s
Luciano

Ademilson Ferreira

unread,
Jul 30, 2009, 10:32:37 AM7/30/09
to python...@yahoogrupos.com.br
2009/7/30 Nycholas de Oliveira e Oliveira <nych...@gmail.com>:

>
>
> :)),
>
> Dica, se você quiser ignorar esses caracteres não ascii utilize a
> normalize do unicodedata.
>
>>>> from unicodedata import normalize
>>>> def nfkd(st):
> ... return normalize('NFKD',
> st.decode('iso-8859-1')).encode('ascii', ''ignore')
>
> ...

Isso não vai apenas ignorar os caracteres não-ascii, ele vai remover
os acentos e cedilha.

Ademilson Ferreira

Henrique Baggio

unread,
Jul 30, 2009, 3:40:49 PM7/30/09
to python...@yahoogrupos.com.br
2009/7/30 Ademilson Ferreira <ademi...@gmail.com>

>
> 2009/7/30 Nycholas de Oliveira e Oliveira <nych...@gmail.com>:
>
> >
> >
> > :)),
> >
> > Dica, se você quiser ignorar esses caracteres não ascii utilize a
> > normalize do unicodedata.
> >
> >>>> from unicodedata import normalize
> >>>> def nfkd(st):
> > ... return normalize('NFKD',
> > st.decode('iso-8859-1')).encode('ascii', ''ignore')
> >
> > ...
>
> Isso não vai apenas ignorar os caracteres não-ascii, ele vai remover
> os acentos e cedilha.

Isso vai ser muito útil pra eu mudar os nomes de uns mp3 que aparecem
errado no display do player do meu carro. =)
>
> Ademilson Ferreira
>
>


--
Henrique Baggio
Computer Engineering - Unicamp

AAACEC - Atlética da Ciência e Engenharia de Computação
Gestão 2009 - Diretoria do 100Nossão
www.ic.unicamp.br/~aaacec

Microsoft Innovation Center - Unicamp
Software Engineer
http://www.lms.ic.unicamp.br
http://lmsu.codeplex.com

Luciano Ramalho

unread,
Jul 30, 2009, 4:46:18 PM7/30/09
to python...@yahoogrupos.com.br
2009/7/30 Ademilson Ferreira <ademi...@gmail.com>:

> 2009/7/30 Nycholas de Oliveira e Oliveira <nych...@gmail.com>:
>>
>>
>> :)),
>>
>> Dica, se você quiser ignorar esses caracteres não ascii utilize a
>> normalize do unicodedata.
>>
>>>>> from unicodedata import normalize
>>>>> def nfkd(st):
>> ... return normalize('NFKD',
>> st.decode('iso-8859-1')).encode('ascii', ''ignore')
>>
>> ...
>
> Isso não vai apenas ignorar os caracteres não-ascii, ele vai remover
> os acentos e cedilha.

Justamente, Ademilson. Caracteres acentuados e cedilhas são não-ASCII.
A tabela ASCII não tem nenhum caractere acentuado.

Dá uma lida aqui:

http://blog.ramgarlic.com/2009/06/o-diabo-da-acentuacao.html

[ ]s
Luciano

alexandre

unread,
Jul 30, 2009, 11:07:24 PM7/30/09
to python...@yahoogrupos.com.br
agradeço pela ajuda.
estou um pouco perdido nas respostas, mas esclareço que o problema não é com
o python e sim com o programa pdftk que eu chamo através de
subproces.call().

no terminal do linux:
$ pdftk química\ I.pdf química\ II.pdf cat output joined.pdf
Error: Failed to open PDF file:
química I.pdf
Error: Failed to open PDF file:
química II.pdf
Errors encountered. No output created.
Done. Input errors, so no output created.

como o problema é do pdftk, o que eu quero é detectar se o nome do arquivo
tem caracteres acentuados e mostrar uma mensagem para renomear os arquivos.
pergunta de leigo: se o nome do arquivo tem caracteres acentuados significa
que ele está codificado com utf-8??


2009/7/30 Luciano Ramalho <ram...@gmail.com>

>
>
> 2009/7/30 Ademilson Ferreira <ademi...@gmail.com<ademilsonfp%40gmail.com>
> >:
>
> > 2009/7/30 Nycholas de Oliveira e Oliveira <nych...@gmail.com<nycholas%40gmail.com>


> >:
> >>
> >>
> >> :)),
> >>
> >> Dica, se você quiser ignorar esses caracteres não ascii utilize a
> >> normalize do unicodedata.
> >>
> >>>>> from unicodedata import normalize
> >>>>> def nfkd(st):
> >> ... return normalize('NFKD',
> >> st.decode('iso-8859-1')).encode('ascii', ''ignore')
> >>
> >> ...
> >
> > Isso não vai apenas ignorar os caracteres não-ascii, ele vai remover
> > os acentos e cedilha.
>
> Justamente, Ademilson. Caracteres acentuados e cedilhas são não-ASCII.
> A tabela ASCII não tem nenhum caractere acentuado.
>
> Dá uma lida aqui:
>
> http://blog.ramgarlic.com/2009/06/o-diabo-da-acentuacao.html
>
> [ ]s
> Luciano
>
>

--
Alexandre Carneiro


[As partes desta mensagem que não continham texto foram removidas]

------------------------------------

alexandre

unread,
Jul 30, 2009, 11:36:35 PM7/30/09
to python...@yahoogrupos.com.br
> Esses caracteres não são exatamente "ilegais" não. Qual erro está
> dando? Mostre o stacktrace completo aí pra ajudar! De repente seria mais
> elegante corrigir o problema exato.
>
> Mas respondendo à sua pergunta... pra saber se algum caractere de uma
> string não é ASCII, às 3:15 da madrugada, eu faria assim:
>
> import string
>
> def tem_caractere_ilegal(s):
> return any(c not in string.ascii_letters for c in s)
>
> --
> []s, Narcélio
>
>
>


não entendi muito bem o uso da função any, mas aqui não funcionou.
>>> import string
>>> def acento(s):
... return any(c not in string.ascii_letters for c in s)
...
>>> s1 = 'química I.pdf'
>>> acento(s1)
True
>>> s2 = 'química II.pdf'
>>> acento(s2)
True
>>> s3 = 'quimica III.pdf' # esse não deveria dar false?
>>> acento(s3)
True

--
Alexandre Carneiro


[As partes desta mensagem que não continham texto foram removidas]

------------------------------------

Iuri

unread,
Jul 31, 2009, 12:00:06 AM7/31/09
to python...@yahoogrupos.com.br
Isso dá erro por causa disso:

>>> string.ascii_letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

O string.ascii_letters contém apenas as letras, portanto um espaço não é
tratado como ascii nesse caso. Portanto essa solução funciona para uma
palavra só. Dá pra fazer algo como string.ascii_letters + ' ' para aceitar
espaços, mas outros caracteres devem ser aceitos também, né? Ponto,
underscore, hifen...

[]s
Iuri

2009/7/31 alexandre <alex...@gmail.com>

Iuri

unread,
Jul 31, 2009, 12:37:08 AM7/31/09
to python...@yahoogrupos.com.br
Pra completar...

Talvez o string.printable talvez resolva seu problema.

>>> string.printable
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:
;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'

Ele possui alguns caracteres inválidos em nomes de arquivo, mas supondo que
suas entradas são nomes de arquivos válidos, isso não é um problema.

def arquivo_nao_ascii(s):
return any(c not in string.printable for c in s)

[]s
Iuri

2009/7/31 Iuri <iuris...@gmail.com>

Alexandre Martani

unread,
Jul 31, 2009, 1:22:09 AM7/31/09
to python...@yahoogrupos.com.br
Uma coisa que não foi dita aqui sobre o exemplo do any, que deve ser
óbvio para muitos, mas talvez seja novidade para alguns.

def tem_caractere_ilegal(s):
return any(c not in string.ascii_letters for c in s)

À primeira vista, pode parecer que a função é ineficiente, pois ela
"parece" montar uma lista de True e False, para depois avaliar se há
algum True. Mas não é assim que funciona. A função do meio é um
generator, ou seja, ela vai gerando um termo por vez, e o any vai
verificando se o termo é verdadeiro, e no primeiro que for, ele já sai
da função.

Para ilustrar, tente entender porque, no exemplo abaixo, o primeiro
entra em loop infinito, enquanto que o segundo chega na resposta
rapidamente.

>>> from itertools import count
>>> any([x == 20 for x in count()])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyboardInterrupt
>>> any(x == 20 for x in count())
True
>>>


--
Alexandre Martani - amartani em gmail com
Sent from Sao Paulo, SP, Brazil


2009/7/31 Iuri <iuris...@gmail.com>:

Narcélio Filho

unread,
Jul 31, 2009, 2:10:15 AM7/31/09
to python...@yahoogrupos.com.br
> (...) o problema não é com o python e sim com o programa pdftk que eu
> chamo através de subproces.call().

> $ pdftk química\ I.pdf química\ II.pdf cat output joined.pdf
> Error: Failed to open PDF file:
> química I.pdf

E como exatamente você está fazendo essa chamada? Será que a culpa
não é do espaço? Será que não precisa usar o encode no nome do arquivo?

subprocess.call(['pdftk', arquivo.encode('utf8')])


> como o problema é do pdftk, o que eu quero é detectar se o nome do
> arquivo tem caracteres acentuados e mostrar uma mensagem para renomear
> os arquivos. pergunta de leigo: se o nome do arquivo tem caracteres
> acentuados significa que ele está codificado com utf-8??

Depende da configuração do seu sistema. No meu tudo é UTF-8 pra
facilitar. Mas é comum sistemas no Brasil serem Latin-1 (ou ISO-8859-1).

No python, eu acho que a regra é algo assim:

1) LOGO DEPOIS de ler uma string do sistema -- seja do sistema de
arquivos, do usuário, da rede ou do banco de dados -- decodifique com:

sua_string = sua_string.decode('codificacao').

2) Trabalhe com o objeto, que agora é unicode, no seu código normalmente;

3) ANTES de escrever no sistema -- seja no sistema de arquivos, na tela,
na rede ou no banco de dados -- recodifique com:

sua_string = sua_string.encode('codificacao')


Ou seja:

# lendo uma string
nome = raw_input()
# decodificando
nome = nome.decode('utf8')
# seu programa complexo aqui que modifica a string
nome = nome.title()
# recodificando
nome = nome.encode('utf8')
# escrevendo de volta pro sistema
print nome


É isso mesmo? Eu sempre apanho dos encodings...


--
[]s, Narcélio

Narcélio Filho

unread,
Jul 31, 2009, 2:25:30 AM7/31/09
to python...@yahoogrupos.com.br
>> Mas respondendo à sua pergunta... pra saber se algum caractere de uma
>> string não é ASCII, às 3:15 da madrugada, eu faria assim:
> não entendi muito bem o uso da função any

Basta ler em inglês mesmo:

any(char not in string.ascii_letters for char in string)
=
Algum caracter não está na string.ascii_letter para todo caracter na string?


> mas aqui não funcionou.

Não funcionou porque eu fico respondendo os emails da lista às 3 da
madrugada sem testar direito os snippets... deixo isso a cargo do
leitor... >:^)

Mas como o Iuri disse, pra esse caso a ascii_letters não serve, pois
nela só tem as letras ascii. Um arquivo, dependendo do sistema
operacional, pode ter vários outros caracteres válidos (como o espaço,
hífen, underscore, etc).


--
[]s, Narcélio

Narcélio Filho

unread,
Jul 31, 2009, 2:29:44 AM7/31/09
to python...@yahoogrupos.com.br
> Ele possui alguns caracteres inválidos em nomes de arquivo, mas supondo que
> suas entradas são nomes de arquivos válidos, isso não é um problema.

E se for o caso, ele ainda pode usar a os.path.isfile():

def arquivo_invalido_segundo_o_julgamento_do_alexandre(filename):
return any(c not in string.printable for c in filename) \
or not os.path.isfile(filename)


--
[]s, Narcélio

Narcélio Filho

unread,
Jul 31, 2009, 2:59:52 AM7/31/09
to python...@yahoogrupos.com.br
> Por sinal, pessoal, vale a pena notar as funções embutidas any, all e
> sum que existem no Python há relativamente pouco tempo e permitem um
> estilo de programação funcional bem esperto e legível.

Exato! E me entristeço muito quando vejo alguém que reclama da
característica "multi-paradigma" do Python.

Ter listas, dicionários e estas funções embutidas na linguagem é uma
vantagem tremenda! E muitos desenvolvedores ainda não perceberam como é
freqüente termos que lidar com problemas que podem ser tratados de forma
simples e *clara* com construções do paradigma funcional. Por exemplo:

Requisito: "Somar o salário dos gerentes no sistema"
Código: sum(func.salario for func in funcionarios if func.tipo == 'gerente')

A maioria deve fazer isso com um for de 4 linhas.

Até o lambda cabe aqui ou ali de vez em quando. E códigos que usem
map() e reduce() já estão prontinhos para a "nuvem"...


--
[]s, Narcélio

Luiz Eduardo Borges

unread,
Jul 31, 2009, 6:47:00 AM7/31/09
to python...@yahoogrupos.com.br

> O Ricbit ou o Dorneles podem dar uma solução em 7 caracteres, mas aí
> eu não sei se vamos entender ;-).

Seria legal ver isso :)

def ascii_puro(s):
return not [c for c in s if ord(c) > 127]

print ascii_puro('a')
print ascii_puro('á')
print ascii_puro(u' a')
print ascii_puro(u'á ')

True
False
True
False

[]s

Danilo Cabello

unread,
Jul 31, 2009, 8:56:07 AM7/31/09
to python...@yahoogrupos.com.br
2009/7/31 alexandre <alex...@gmail.com>:

> como o problema é do pdftk, o que eu quero é detectar se o nome do arquivo
> tem caracteres acentuados e mostrar uma mensagem para renomear os arquivos.
> pergunta de leigo: se o nome do arquivo tem caracteres acentuados significa
> que ele está codificado com utf-8??

como a discussão está disvirtuando pra outra coisa que não é a solução
do seu problema, vou tentar ajudar aqui:

dependendo do seu volume de dados, eu faria o seguinte, copie o
arquivo química pra uma pasta temp e guarde sua relação química 1 =
axDds.pdf, faça o mesmo com o quimica 2, e manda o seu programinha de
pdf juntar esses arquivos temporários sem acentos, que você acha?

depois você deleta os pdfs temporários, daí você salva com o nome que
quiser o arquivo até com acento, pois pelo que você está reclamando é
o programinha de juntar pdf que não gosta de arquivos acentuados

alexandre

unread,
Jul 31, 2009, 10:54:33 AM7/31/09
to python...@yahoogrupos.com.br
> dependendo do seu volume de dados, eu faria o seguinte, copie o
> arquivo química pra uma pasta temp e guarde sua relação química 1 =
> axDds.pdf, faça o mesmo com o quimica 2, e manda o seu programinha de
> pdf juntar esses arquivos temporários sem acentos, que você acha?
>
> depois você deleta os pdfs temporários, daí você salva com o nome que
> quiser o arquivo até com acento, pois pelo que você está reclamando é
> o programinha de juntar pdf que não gosta de arquivos acentuados
>

exatamente!

vou testar a sua sugestão.
mas como os pdf são grandes vou ter de testar a acentuação antes de partir
pra cópia.

talvez se eu guardasse os nomes dos arquivos, renomea-se, fizesse o joiner e
depois renomea-se novamente com os nomes originais...
acho que teria menos impacto nos recursos do sistema.


--
Alexandre Carneiro


[As partes desta mensagem que não continham texto foram removidas]

------------------------------------

Ademilson Ferreira

unread,
Jul 31, 2009, 12:43:08 AM7/31/09
to python...@yahoogrupos.com.br
2009/7/30 Luciano Ramalho <ram...@gmail.com>:

>
>
> 2009/7/30 Ademilson Ferreira <ademi...@gmail.com>:
>
>> 2009/7/30 Nycholas de Oliveira e Oliveira <nych...@gmail.com>:
>>>
>>>
>>> :)),
>>>
>>> Dica, se você quiser ignorar esses caracteres não ascii utilize a
>>> normalize do unicodedata.
>>>
>>>>>> from unicodedata import normalize
>>>>>> def nfkd(st):
>>> ... return normalize('NFKD',
>>> st.decode('iso-8859-1')).encode('ascii', ''ignore')
>>>
>>> ...
>>
>> Isso não vai apenas ignorar os caracteres não-ascii, ele vai remover
>> os acentos e cedilha.
>
> Justamente, Ademilson. Caracteres acentuados e cedilhas são não-ASCII.
> A tabela ASCII não tem nenhum caractere acentuado.
>
> Dá uma lida aqui:
>
> http://blog.ramgarlic.com/2009/06/o-diabo-da-acentuacao.html
>
> ...

Entendi, eu quis dizer é q o caracter vai desacentuar. O normalize faz
com que os caracteres acentuados "sejam separados dos acentos" (não
sei se é a melhor forma para descrever o comportamento).

Ademilson Ferreira

caio ariede

unread,
Jul 31, 2009, 8:44:46 AM7/31/09
to python...@yahoogrupos.com.br
Outra solução, um pouco menos elegante:

>>> def has_unicode(s):
... return not unicode(s, errors='ignore') == s
...
>>> has_unicode('química')
True
>>> has_unicode('quimica')
False

Caio Ariede
http://caioariede.com/

2009/7/31 Luiz Eduardo Borges <lu...@yahoo.com.br>:

Leonardo Santagada

unread,
Jul 31, 2009, 11:33:39 AM7/31/09
to python...@yahoogrupos.com.br

On Jul 31, 2009, at 11:54 AM, alexandre wrote:

>> dependendo do seu volume de dados, eu faria o seguinte, copie o
>> arquivo química pra uma pasta temp e guarde sua relação química 1 =
>> axDds.pdf, faça o mesmo com o quimica 2, e manda o seu programinha de
>> pdf juntar esses arquivos temporários sem acentos, que você acha?
>>
>> depois você deleta os pdfs temporários, daí você salva com o nome que
>> quiser o arquivo até com acento, pois pelo que você está reclamando é
>> o programinha de juntar pdf que não gosta de arquivos acentuados
>>

> exatamente!
>
> vou testar a sua sugestão.
> mas como os pdf são grandes vou ter de testar a acentuação antes de
> partir
> pra cópia.
>
> talvez se eu guardasse os nomes dos arquivos, renomea-se, fizesse o
> joiner e
> depois renomea-se novamente com os nomes originais...
> acho que teria menos impacto nos recursos do sistema.


O que eu já pensei uma vez era dentro da aplicação que gera esses
arquivos pegar o nome em unicode, fazer o encoding pra utf-8 e depois
fazer um base64 no nome para nomear num sistema de arquivos. É chato
pois todos lendo o arquivo tem q fazer o base64, mas evita que um
sistema de arquivos com encoding mal configurado estrague o nome dos
arquivos.

Provavelmente ninguém nunca fez isso porque em aplicações maiores
sempre é usado um banco de dados que guarda o nome do arquivo e os
arquivos no disco geralmente são uma hash do nome ou algo sem nehuma
relação com o nome.

--
Leonardo Santagada
santagada at gmail.com

alexandre

unread,
Jul 31, 2009, 10:30:32 PM7/31/09
to python...@yahoogrupos.com.br
2009/7/31 alexandre <alex...@gmail.com>

>
> dependendo do seu volume de dados, eu faria o seguinte, copie o
>> arquivo química pra uma pasta temp e guarde sua relação química 1 =
>> axDds.pdf, faça o mesmo com o quimica 2, e manda o seu programinha de
>> pdf juntar esses arquivos temporários sem acentos, que você acha?
>>
>> depois você deleta os pdfs temporários, daí você salva com o nome que
>> quiser o arquivo até com acento, pois pelo que você está reclamando é
>> o programinha de juntar pdf que não gosta de arquivos acentuados
>>
>
>
>
>
>
>
>
>
>
>
>
> exatamente!
>
> vou testar a sua sugestão.
> mas como os pdf são grandes vou ter de testar a acentuação antes de partir
> pra cópia.
>
> talvez se eu guardasse os nomes dos arquivos, renomea-se, fizesse o joiner
> e depois renomea-se novamente com os nomes originais...
> acho que teria menos impacto nos recursos do sistema.
>
>
> --
> Alexandre Carneiro
>

agradeço a todos pela aula.
o meu script não ficou tão elegante mas saiu.

from tkMessageBox import *
from Tkinter import *
from subprocess import *
from os.path import *
import os, sys


Tk().withdraw()


def main():
"""
pdftk %files cat output joined.pdf
"""
files = sys.argv[1:]
d = dirname(files[0])
os.chdir(d)

for f in files:
if(unicode(f, errors='ignore') == f):
fren = []
for i,f in enumerate(files):
nome = str(i) + '.pdf'
os.rename(f, nome)
fren.append(nome)
break

if fren:
cmd = ['pdftk'] + fren + ['cat','output',join(d,'joined.pdf')]
else:
cmd = ['pdftk'] + files + ['cat','output',join(d,'joined.pdf')]

r = call(cmd)

if fren:
for i,f in enumerate(files):
os.rename(fren[i], f)


if(r == 0):
showinfo('pdf_joiner.py v0.1', 'Operação realizada com sucesso!')
else:
showerror('erro!', str(r))

if __name__=='__main__':
main()

Reply all
Reply to author
Forward
0 new messages