3

I'm doing Learn Python the Hard Way exercise 35. Below is the original code, and we're asked to change it so it can accept numbers that don't have just 0 and 1 in them.

def gold_room(): print "This room is full of gold. How much do you take?" next = raw_input("> ") if "0" in next or "1" in next: how_much = int(next) else: dead("Man, learn to type a number.") if how_much < 50: print "Nice, you're not greedy, you win!" exit(0) else: dead("You greedy bastard!") 

This is my solution, which runs fine and recognizes float values:

def gold_room(): print "This room is full of gold. What percent of it do you take?" next = raw_input("> ") try: how_much = float(next) except ValueError: print "Man, learn to type a number." gold_room() if how_much <= 50: print "Nice, you're not greedy, you win!" exit(0) else: dead("You greedy bastard!") 

Searching through similar questions, I found some answers that helped me write another solution, shown in the below code. The problem is, using isdigit() doesn't let the user put in a float value. So if the user said they want to take 50.5%, it would tell them to learn how to type a number. It works otherwise for integers. How can I get around this?

def gold_room(): print "This room is full of gold. What percent of it do you take?" next = raw_input("> ") while True: if next.isdigit(): how_much = float(next) if how_much <= 50: print "Nice, you're not greedy, you win!" exit(0) else: dead("You greedy bastard!") else: print "Man, learn to type a number." gold_room() 
1
  • 3
    Do not use next as a variable name. That is a function in Python. Commented Apr 25, 2014 at 22:20

6 Answers 6

4

isinstance(next, (float, int)) will do the trick simply if next is already converted from a string. It isn't in this case. As such you would have to use re to do the conversion if you want to avoid using try..except.

I would recommend using the try..except block that you had before instead of a if..else block, but putting more of the code inside, as shown below.

def gold_room(): while True: print "This room is full of gold. What percent of it do you take?" try: how_much = float(raw_input("> ")) if how_much <= 50: print "Nice, you're not greedy, you win!" exit(0) else: dead("You greedy bastard!") except ValueError: print "Man, learn to type a number." 

This will try to cast it as a float and if it fails will raise a ValueError that will be caught. To learn more, see the Python Tutorial on it.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried this code and it worked well. Thank you. It is a good solution, but since he hasn't yet introduced try/except statements, I think the answer provided by Slick is more along the lines of what the author was looking for.
@pez Slick uses as try except as well
Oops, sorry. I got mixed up looking at something else. Yes, then both your codes are appropriate and efficient.
1

RE would be a good choice

>>> re.match("^\d+.\d+$","10") >>> re.match("^\d+.\d+$","1.00001") <_sre.SRE_Match object at 0x0000000002C56370> 

If the raw input is a float number, it will return an object. Otherwise, it will return None. In case you need to recognize the int, you could:

>>> re.match("^[1-9]\d*$","10") <_sre.SRE_Match object at 0x0000000002C56308> 

Comments

1

You can use a regex to validate the format:

r'^[\d]{2}\.[\d]+$' 

You can found the documentation here: https://docs.python.org/2/library/re.html

Comments

1

The problem I have with your approach is that you're going down a path of "Look Before You Leap" instead of the more Pythonic "Easier to Ask Forgiveness than Permission" path. I think your original solution is better than trying to validate the input in this way.

Here is how I would write it.

GREEDY_LIMIT = 50 def gold_room(): print("This room is full of gold. What percent of it do you take?") try: how_much = float(raw_input("> ")) except ValueError: print("Man, learn to type a number.") gold_room() return if how_much <= GREEDY_LIMIT: print "Nice, you're not greedy, you win!" exit(0) else: dead("You greedy bastard!") 

4 Comments

Your code is simple and efficient, and it worked well. Thank you. I like this answer best so far, because it doesn't use any concepts that I haven't learned yet. He has not introduced try/except statements yet, so I feel this answer would be along the lines of what he expects from us.
@pez If you find an answer useful, it is good habit to express it by upvoting (any number of answers), or finally even accepting an answer (only one).
@ Jan Vlcinsky Thanks for the advice. I can't upvote anything yet because I'm a new user, and that requires a reputation of 15. I'm thinking of which answer to accept since multiple ones are valid.
This is wrong. When you call gold_room() at the end of the except clause, you are starting a recursive stack of calls that will cause unexpected behavior if this is used and the user inputs a non float value.
0

use below python based regex checking for float strings

import re a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' , '2.3') a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' , '2.') a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' , '.3') a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' , '2.3sd') a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' , '2.3') 

output: !None, !None, !None, None , !None then use this output to do conversions.

1 Comment

why downvote . it best solution among all existing posted solution ? COuld you reason then just downvote!
0

If you don't want to use try/except, below is my answer :

def gold_room(): print "This room is full of gold. How much do you take?" choice = input("> ") if choice.isdigit(): how_much = int(choice) elif "." in choice: choice_dot = choice choice_dot_remove = choice_dot.replace(".","") if choice_dot_remove.isdigit(): how_much = float(choice) else: dead("Man, learn to type a number.") if how_much < 50: print "Nice, you're not greedy, you win!" exit(0) else: dead("You greedy bastard!") 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.