----------------------------------------------------------------------------------
Pretendo criar um programa que conte o número de ocorrências que cada
palavra tem num ficheiro. Parti do exercício do exame, uma vez que
tenho que retirar sinais de pontuação.
Tenho este código mas não consigo continuar.
01.
def
conta_palavras():
02.
a
=
open(
'texto.txt'
,
'r'
)
03.
tex
=
a.read().split()
04.
txt
=
[]
05.
sinais
=
[
'!'
,
','
,
'.'
,
':'
]
06.
for
palavra
in
tex:
07.
if
palavra[
-
1
]
in
sinais:
08.
palavra
=
palavra[:
-
1
]
09.
txt.append(palavra)
10.
else
:
11.
palavra
=
palavra
12.
txt.append(palavra)
------------------------------------------------------------------------------------
Olhando para o que está feito, e sabendo que a solução do exame foi colocada aqui neste blogue, fica-me a convicção que @ alun@ não sabe da sua existência. Esta situação de ignorância foi confirmada recentemente pela quantidade de alun@s que apareceram para ver o exame mas que desconheciam a existência do blogue, logo nem sequer tinham visto a respectiva solução. É um espanto! Curiosamente tenho tido feedback de pessoas de outros países que estão a seguir o que aqui tenho colocado. Sinal dos tempos!!
Olhando para o código, verifico que a parte para obter a lista de palavras está mais ao menos aceitável. Algumas notas:
a) O nome do ficheiro não é dado como parâmetro da função, o que é uma má prática de programação;
b) Deve-se procurar usar nossos que tenham algum significado. Se um programa tiver centenas de milhares de linhas de código, aparecer por lá um a diz pouco do que é e para que serve;
c) Há uma ineficiência no if: fazer palavra = palavra, serve para quê? Por outro lado, o código pode encolher:
1.
for
palavra
in
text:
2.
if
palavra[
-
1
]
in
sinais:
3.
palavra
=
palavra[:
-
1
]
4.
txt.append(palavra)
Agora vamos voltar ao problema. Uma coisa que devem procurar fazer é construir o programa passo a passo, deixando claro a vossa estratégia. Por exemplo, neste caso seria algo como:
01.
def
fich_dic(ficheiro):
02.
""" Lê o conteúdo do ficheiro e constrói um dicionário
03.
com chave uma palavra e valor o número de vezes que a palavra
04.
ocorre no texto.
05.
"""
06.
# obter a lista de palavras
07.
# filtra os sinais
08.
# constrói dicionário
09.
return
# dicionário
Aparentemente avançámos pouco, mas pelo menos temos as tarefas bem identificadas e podemos passar a resolver as que sabemos resolver sem pensar muito:
1.
# obter a lista de palavras
2.
f_in
=
open(ficheiro,
'r'
)
3.
lista_pal
=
f_in.read().split()
Que sinais vamos querer filtrar, e onde podem aparecer? Admitamos que podem aparecer no final, ou isolados, mas sempre só um símbolo. Outra decisão importante é saber se usamos a lista de palavras que já temos ou se fabricamos uma nova. Tendo decidido podemos passar a uma solução:
01.
# filtra os sinais
02.
especiais
=
[
'\n'
,
'.'
,
','
,
'!'
,
'?'
]
03.
lista_final
=
[]
04.
for
palavra
in
lista_pal:
05.
# símbolos especiais fora
06.
if
palavra
in
especiais:
07.
continue
08.
elif
palavra[
-
1
]
in
especiais:
09.
palavra
=
palavra[:
-
1
]
10.
# acrescenta
11.
lista_final.append(palavra)
Todas as decisões estão claras no código: símbolo isolado ou no final, nova lista. Reparar que esta solução torna trivial mudarmos os sinais a considerar. Imagine agora que pode ter outras marcas, como tabulações (‘\t’) ou outras. Acha que se resolve a questão, aumentando apenas a listas de sinais? É que este tem dois símbolos?! Experimente fazer:
01.
# filtra os sinais
02.
especiais
=
[
'\n'
,
'.'
,
','
,
'!'
,
'?'
,
'\t'
]
03.
lista_final
=
[]
04.
for
palavra
in
lista_pal:
05.
# símbolos especiais fora
06.
if
palavra
in
especiais:
07.
continue
08.
elif
palavra[
-
1
]
in
especiais:
09.
palavra
=
palavra[:
-
1
]
10.
elif
palavra[
-
2
:]
in
especiais:
11.
palavra
=
palavra[:
-
2
]
12.
# acrescenta
13.
lista_final.append(palavra)
E verá a surpresa. Mesmo com o teste não funciona!. É que na realidade as marcas de controlo vão ter uma tradução ... bizarra: em vez de ‘\t’ aparece ’\\t’! Coisas. E se tiver marcas com mais símbolos? Pense um pouco e veja como resolvia a questão.
Mas voltemos à questão de querer manter a lista de palavras inicial. Uma solução simples seria:
1.
# filtra os sinais
2.
especiais
=
[
'\n'
,
'.'
,
','
,
'!'
,
'?'
]
3.
for
indice,palavra
in
enumerate(lista_pal):
4.
if
palavra
in
especiais:
5.
lista_pal.remove(palavra)
6.
elif
palavra[
-
1
]
in
especiais:
7.
lista_pal[indice]
=
palavra[:
-
1
]
Note-se o recurso a enumerate!
Agora a construção do dicionário. Não há muito a dizer. A chave são as palavras, e os valores inteiros. Sendo os valores objectos imutáveis podemos usar o método get, e eis a solução para esta parte.
1.
# Constrói dicionário
2.
dic
=
{}
3.
for
palavra
in
lista_final:
4.
dic[palavra]
=
dic.get(palavra,
0
)
+
1
5.
return
dic
Como explicámos nas aulas e também neste blogue o método get é uma fprma elegante de resolver esta questão: Se a palavra ainda não estiver no dicionário, o método devolve o valor por defeito (0), que é somado a 1 , sendo o novo para colocado no dicionário. Se existir, devolve o valor que é na mesma somado e actualizado.
Vamos agora juntar todos os bocados:
01.
def
fich_dic(ficheiro):
02.
""" Lê o conteúdo do ficheiro e constrói um dicionário
03.
com chave uma palavra e valor o número de vezes que a palavra
04.
ocorre no texto.
05.
"""
06.
# obter a lista de palavras
07.
f_in
=
open(ficheiro,
'r'
)
08.
lista_pal
=
f_in.read().split()
09.
# filtra os sinais
10.
especiais
=
[
'\n'
,
'.'
,
','
,
'!'
,
'?'
]
11.
lista_final
=
[]
12.
for
palavra
in
lista_pal:
13.
# símbolos especiais fora
14.
if
palavra
in
especiais:
15.
continue
16.
elif
palavra[
-
1
]
in
especiais:
17.
palavra
=
palavra[:
-
1
]
18.
# acrescenta
19.
lista_final.append(palavra)
20.
# Constrói dicionário
21.
dic
=
{}
22.
for
palavra
in
lista_final:
23.
dic[palavra]
=
dic.get(palavra,
0
)
+
1
24.
return
dic
Sem comentários:
Enviar um comentário