Ir para o conteúdo
PsySc0rpi0n

Verificação do user input

Mensagens Recomendadas

PsySc0rpi0n

Estou a tentar fazer um simples programa mas ainda não consegui!

Estou a pedir ao user um valor. E quero certificar-me que é um número... Numérico... Não alfanumérico!

Já tentei várias abordagens mas ainda não consegui:

from math import frexp
number = float(raw_input("Enter a number:"))
print "Type is: {}".format(type(number))

Até aqui tudo bem.

Mas depois para verificar se é um valor numérico estou a fazer:

while number.isdigit() == False
   print "That is not a number! Try again!"
   number = float(raw_input("Enter a number:"))

Mas isto dá erro:

AttributeError: 'float' object has no attribute 'isdigit'

Como é que faço isto se os floats não têm o método isdigit???

Editado por PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
djthyrax

Se a memória não me falha (não tenho aqui Python instalado), se tentares fazer float() de algo que não seja válido, é feito raise de uma excepção. É uma questão de apanhares a mesma e fazeres o que precisas :)


Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Ainda não cheguei a esse ponto das exceptions mas vou ver disso.


Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Tentei assim mas continua a dar erro...

Eu percebo porquê e para corrigir o erro bastava fazer um cast para float aquando do "raw_input" mas assim a função validate passa a ser redundante e se eu colocar lá "45.a", isto é convertido para float e portanto o retorno da função validate é sempre True, acho eu!

from math import frexp as frexp

def validate(userInput):
   try:
       type(userInput) == float
       valid = True
   except Exception:
       valid = False
   return valid

number = raw_input("Enter a number: ")
print "Type is: {}".format(type(number))#just for debug purposes

print "Validate return value: {}".format(validate(number))

while validate(number) == False:
   print "That is not a number! Try again!"
   number = raw_input("Enter a number: ")

print "{}".format(frexp(number))

Editado por PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Acabei por fazer assim:

from math import frexp

check = 0
number = raw_input("Enter a number:")

while check != 1:
   try:
       number = float(number)
       print "{}".format(frexp(number))
       check = 1
   except Exception:
       print "That is not a number!"
       number = raw_input("Enter a number:")

Mas não faço ideia se o método é correcto ou se é solução de pedreiro.

Editado por PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

PsySc0rpi0n,

Estás a fazer confusão com várias coisas em simultâneo. Vamos por partes.

Em primeiro lugar, interessa perceber que isdigit() só existe em strings. Por esse motivo, quando defines number = float(...) e depois tentas fazer number.isdigit() é-te devolvido um erro (e muito bem!) que indica que esse atributo não existe para objectos do tipo float, apenas para os do tipo str.

Outra questão importante: ao utilizares isdigit(), estarias a perder todos os casos onde o float tivesse casas decimais, pois esta função só devolve True para números inteiros.

Passemos então ao penúltimo excerto de código que colocaste.

A tua validate() vai ser sempre verdadeira. Isto acontece porque tu tens uma linha onde perguntas se type(userInput) == float, mas como essa condição não está inserida num if, o resultado (seja ele True ou False) nunca será utilizado. Na linha seguinte defines que valid = True (isto acontece sempre) e, uma vez que não há aqui hipótese alguma de haver uma excepção, o valor final será sempre True.

Para que a excepção funcionasse como queres, a conversão para float teria que acontecer dentro de validate().

Por estes motivos, a execução do teu código diria sempre que o tipo é str e que validate() foi True, falhando depois na aplicação de frexp pois não terias um float.

Algumas outras coisas que me incomodam:

  • Escreve apenas from math import frexp (acrescentar as frexp fica mal)
  • Já te expliquei que print "{}".format(...) é o mesmo que escrever print ... (ou seja, se a tua string de formatação é apenas "{}" não uses format!)

E agora o último excerto de código:

O ideal seria abstraires o conceito de «pedir um float ao utilizador» para uma função. Dessa forma, podes depois utilizar a função de forma mais clara:

def ask_for_float():
   try:
       return float(raw_input('Float? '))
   except ValueError:
       # Não era um float válido, devolvemos None
       return None

have_float = False
while not have_float:
   f = ask_for_float()
   have_float = f != None  # Se f não for None, então have_float é True

   # Podemos imprimir uma mensagem de erro aqui 
   if f is None:
       print "That is not a number!"

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Pois, os primeiros pedaços de código já tinham ido à vida. Já iniciei este post há uns dias.

Mas o teu code apenas verifica se o que foi inserido é um float ou não, certo?

Depois ainda tenho que incorporar a função que quero usar.


Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

Já iniciei este post há uns dias.

Ontem :P

Sim, o meu código faz isso. O teu também, mas mistura mais coisas, nomeadamente o processo de pedir o número, verificar se é válido e emitir avisos.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Ontem :P

Sim, o meu código faz isso. O teu também, mas mistura mais coisas, nomeadamente o processo de pedir o número, verificar se é válido e emitir avisos.

Pois, parecia ter sido há mais dias!

Deixa cá tentar então usar esse code e alterar o meu!

Outra coisa, o frexp devolve um tuple... É possível separar aqueles dois valores e usá-los para outros fins?


Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Ok, já vi como decompôr um tuple... É mais fácil que o que parece!

Fiz assim...

from math import frexp

def ask_for(typ, prompt):
   try:
       return typ(raw_input(prompt))
   except ValueError, TypeError:
       print 'Invalid {!r} value.'.format(typ)

mant = 0.0 
exp  = 0 
isfloat = False
while not isfloat:
   number = ask_for(float, "Enter a number: ")
   isfloat = (number != None)
   if number is not None:
       mant, exp = frexp(number)
       print "The mantissa is {} and the exponent is {}!".format(mant, exp)

Está melhor???


Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Sim, bastante melhor :)

Eu já estive a ler sobre aquele

!r

mas não percebi muito bem como e quando aquilo se pode usar e o que aquilo faz...


Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

PsySc0rpi0n,

Tens que começar por perceber o que faz a função repr() (vê em Built-in functions), mas essencialmente a sua função é devolver uma representação textual de um objecto.

O especificador !r dentro de uma string de formatação é meramente um atalho para essa função repr(), assim:

a = [ 1, 2, 3, 4, 5 ]

# em vez disto:
print "a = {}".format(repr(a))

# podes escrever isto:
print "a = {!r}".format(a)

Tudo isto tem muito mais importância quando crias objectos e classes tuas, e queres definir uma representação textual decente... Para os tipos de dados pré-definidos, o resultado é bastante previsível.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Ok, assim acho que já percebi! E pode-se fazer isso para outras built-in functions ou é só para essa? Onde posso ver os atalhos que existem???


Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

Tens aqui: Format specification mini-language. De qualquer modo, os únicos atalhos suportados são para repr() e str (!r e !s, respectivamente).

Nota: tenho-te dado os links para a documentação do Python 2.7.x, pois sei que estás no Codecademy e é essa versão que utilizam. No entanto, eventualmente deverás pensar em mudar para o Python 3.x, ok? É mais actual e mais saudável para quem está a começar :)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Pois.. Eu to smartphone ando com uma cena parecida ao CodeAcademy mas com aversão 3.x...


Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

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.