Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #59 da revista programar. Faz já o download aqui!

Guest Shad07

[Resolvido] teclas_palavras

Mensagens Recomendadas

Guest Shad07   
Guest Shad07

Boa noite,

Precisava de ajuda, porque não sei como começar o código, estou sem ideias.

Desde já um obrigado a quem conseguir dar uma ajuda.

Editado por Shad07

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo    223
pwseo

O teu código está desformatado, coloca-o correctamente dentro das tags CODE.

Quanto à tua dúvida, isso acontece porque tu estás a percorrer os números um de cada vez. Por outras palavras, o teu programa nunca chega a ver 55 -- apenas consegue ver 5 duas vezes (embora sejam seguidas).

Corrigir não é difícil: basta leres os números até que apareça um espaço ou um número diferente, e só depois é que vais ver qual a letra correspondente aos números que leste.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo    223
pwseo

Shad07,

Na minha opinião, nem precisas de um dicionário, basta-te uma lista de strings:

chars = [ '.,?!', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz' ]

Imaginando que tens agora a string 777, podes definir as seguintes variáveis:

  • x = a conversão para int do primeiro char da string (ou seja, 7)
  • y = o tamanho da string (ou seja, 3)

Assim:

s = '777'
x = int(s[1])
y = len(s)

print(chars[x - 1][y - 1])  # imprime 'r'

Agora só tens que arranjar uma forma de separar uma string como '2 22 222 334' em vários grupos de códigos.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo    223
pwseo

1. A ideia é desenvolveres uma função que faça isso. É esse o cerne do problema (e é isso que não vamos resolver por ti). O gonca16 teve que fazer um esquema de uma máquina de estados... não é o mesmo caso para ti?

Em alternativa, podes fazer uma função que leia a string original um char de cada vez e vá emitindo o output necessário.

2. Tens que utilizar o operador % do Python. Também falei disso no tópico do gonca16

3. Se quiseres utilizar o espaço sim, também tens que o colocar. Eu provavelmente colocá-lo-ia no início da lista, por ser a tecla zero.

Adenda: Se quiseres emular o comportamento de outras teclas como o * e + será mais simples se usares um dicionário (eu falei da lista porque não estava a pensar nessas teclas).

Editado por pwseo

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo    223
pwseo

Ora bem, vamos por partes.

Este framento de código é aquilo que se designa de «lista por compreensão», uma forma muito compacta de construir listas novas que resultam da transformação de uma lista anterior. Neste caso, a transformação em causa é a aplicação de tochar a cada elemento.

# isto:
[ tochar(c) for c in codes(keys) ]

# é o mesmo que isto:
result = []
for c in codes(keys):
   result.append(tochar(c))
return result

Juntar tudo numa função principal é canja, eu até dei esse pedaço de código «de barato»:

# Esta função junta o trabalho de tochar() e codes()
def decode(keys):
   return [ tochar(c) for c in codes(keys) ]

Relativamente às tuas funções, não funcionam correctamente.

A tua tochar() nem sequer compila correctamente, repara bem no código que escreveste. Consegues perceber por que motivo não está correta?

Em relação à split(), se fosse tão simples quanto utilizar a string.split() eu não teria dito que era necessário criarem uma função para isso.

Repara como ela falha:

>>> split('123')
['1223334444']

O esperado seria devolver ['1', '22', '333', '4444'].

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo    223
pwseo

Sim, estou a par desses pormenores.

Na versão que tenho funciona:

>>> decode('222 2333 33')
'cafe'
>>> decode('7288888')
'pau'

Para resolveres o primeiro problema, tens que arranjar uma forma de dividir a string original em grupos de teclas... é essa função que te falta: dá uma olhadela na função groupby() do módulo itertools.

Para resolveres o segundo problema, tens que utilizar o operador % para obter a posição correcta da letra, quando há muitas repetições. Também falei disto no tópico do gonca16.

Editado por pwseo

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Guest Shad07   
Guest Shad07

Na minha da aquele erro que enviei na resposta acima, no decode, não percebo porquê ...

Então deixa ver se percebi , falta-me uma função que agrupe as teclas ?

Editado por Shad07

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo    223
pwseo

Sim, tens que agrupar de modo a que '222 2333 33' seja transformado em ['222', '2', '333', '33'] (actualmente o que acontece é ['222', '2333', '33'], e o erro surge nesse contexto).

Chegaste a ver a função groupby do módulo itertools como te disse? Faz precisamente o que pretendes. Só não podes utilizar essa função se o objectivo for obrigar-vos a escrever algo que tenha o mesmo comportamento de raíz.

Editado por pwseo
Adicionada nota sobre itertools.groupby()

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Guest Shad07   
Guest Shad07

Vou ver isso que disseste agora

Não existe nenhuma restrição em termos de que ferramentas podemos usar, desde que o programa funcione com deve ser.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo    223
pwseo

esta é a função groupby(), mas tenho dificuldade em saber o que substituir na função.

Sim, eu sei qual é a função groupby(). O exemplo que tens aí é desnecessariamente complexo, no teu caso podes utilizá-la sem o segundo argumento, como foi feito no tópico do gonca16.

Repara neste exemplo:

from itertools import groupby

grupos = []
for _, g in groupby('1223 334444'):
   grupos.append(''.join(g))

print(grupos)  # ['1', '22', '3', ' ', '33', '4444']

Repara que tens um elemento ' ' que é necessário eliminar. Deixo isso como exercício para fazeres.

Como é que te deu correto naquelas duas excepções?

Simples. O meu código sabe agrupar correctamente os dígitos e faz uso do operador %, como já indiquei anteriormente.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo    223
pwseo

Em qual das funções é que teria de usar o operador %?

Onde achas que seria necessário? Se calhar não é ao dividir a string em grupos mas sim ao converter um grupo para uma letra. Não posso dizer muito mais sem escrever o código eu mesmo...

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo    223
pwseo

Shad07,

Já testaste o código que tens? A tua função teclas_para_palavras() não funciona.

Relativamente ao %, que confusão. A ideia é pegares no comprimento do código que estás a processar e ver o resto da divisão disso pelo número de letras presentes numa tecla.

Exemplo: '88888' tem comprimento 5 (chamemos a isto 'x'). A tecla 8 tem 3 letras ('tuv'); chamemos a isto 'y'). Agora fazemos x % y, ou seja, 5 % 3 cujo resultado será 2 (queremos a segunda letra, portanto!).

Por motivos matemáticos (nos quais não me alongarei), ao valor de x deve ser subtraido 1 antes de fazer a operação com o %, e portanto fazemos (x - 1) % y cujo valor final é 1, o índice da letra 'u' na string 'tuv'.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.