python 2.7 isnan() function not working - python

I am having a slight issue with math's .isnan() function in python. Pretty much, I have this code:
import math
diceChoice = raw_input('Which dice will you throw?\n 4 sides\n 6 sides\n 12 sides?\n>')
if math.isnan(float(diceChoice)):
print(str(diceChoice) + ' is an invalid choice')
and if diceChoice isn't a number (eg 'a') it gives me the error:
ValueError: could not convert string to float: a
If I don't convert it to a float, it gives me another error saying that it needs to be a float. I must be doing something wrong as the isnan function would be useless if it only accepts numbers. Can someone please help me
Thanks in advance

The float() function used on any other string other than a decimal number, 'nan', '-inf' or 'inf' (or slight variants of those strings) will throw a ValueError instead, because anything else is not a valid floating point value. math.isnan() only works on the special float value float('nan'), but it is not ever called if float() raises an exception first.
Use exception handling to catch that error instead:
try:
diceChoice = int(diceChoice))
except ValueError:
print(diceChoice, 'is an invalid choice')
I used int() instead because your input requires that the user enters a whole number.
Just to be explicit: float('nan') is a specific floating point value to signify the output of certain mathematical operations that are not an exception. It is never used to signify invalid input.

isnan() is really only used to check if a number doesn't have a finite value. Consider instead doing something like:
if not diceChoice.isdigit():
The error is raised because you attempt to convert a string to an integer with float('a'). Easier to just do the above.

NaN are used to define things that are not numbers in a floating point context like 0/0 or the square root of a negative number for example. You can use isdigit or something else.

Related

Getting error in python: Value Error: invalid literal for int() with base 10: '470.21'

i want adding and subtracting this type of data: $12,587.30.which returns answer in same format.how can do this ?
Here is my code example:
print(int(col_ammount2.lstrip('$'))-int(col_ammount.lstrip('$')))
I removed $ sign and convert it to int but it gives me base 10 error.
You mentioned you want to do arithmetic operations to the numbers (addition/subtraction) so you probably want them in float instead. The difference between an integer (int) and float is that integers do not carry decimal points.
Additionally, as #officialaimm mentioned you need to remove the commas too, for example
float('$3,333.33'.replace('$', '').replace(',', ''))
will give you
3333.33
So putting it into your code
print(float(col_ammount2.lstrip('$').replace(',', ''))
- float(col_ammount.lstrip('$').replace(',', '')))
An additional note for when you parse a floating point number (same applies to integers too), you may want to watch out for empty values, i.e.
float('')
is bad. One of the things u can do in case col_amount and col_amount2 may be empty at some point is default them to 0 if that happens
float(col_amount.lstrip(...).replace(...) or 0)
You also want to read this to know about workaround to problems you may face with floating point arithmetic https://docs.python.org/3/tutorial/floatingpoint.html
There are two things you are missing here. Firstly python int(...) cannot parse numbers with commas so you will need to remove commas as well by using .replace(',',''). Secondly int() cannot parse floating point values you will have to use float(...) first and after that maybe typecast it to int using int or math.ceil, math.floor appropriately as per your choice and needs.
Maybe something like this will solve your problem:
col_ammount2='$1,587.30'
col_ammount = '$2,567.67'
print(int(float(col_ammount2.lstrip('$').replace(',','')))-int(float(col_ammount.lstrip('$').replace(',',''))))
If you are doing these sorts of things quite often in your code, making a function as such might be handy:
integerify_currency = lambda x:int(float(x.lstrip('$').replace(',','')))

How to determine the type of input? [duplicate]

This question already has answers here:
How to accept the input of both int and float types?
(6 answers)
Closed 5 years ago.
I'm trying to make a factorial calculator.
Input and Expected output:: If the user input is a positive integer, I want the program to give the outcome. And if the user input is not a positive integer(negative integer, float, or string), I want the program to ask for the input again. Also, I want the program to end when the user input is 0.
Problem: Since inputs are always perceived as string data, I am stuck with coding according to the type of input.
It would be of great help if someone would give answers to this problem, as I am studying by myself.
If you want to ensure it's a positive integer, and if you want to keep asking for input as specified in your question, you'll need a few more control structures:
from math import factorial
def get_input():
while True:
try:
inp = int(input("Enter a positive integer> "))
if inp < 0:
raise ValueError("not a positive integer")
except ValueError as ve:
print(ve)
continue
break
return inp
print(factorial(get_input()))
This works by just trying to convert the input to an integer, and retrying if this fails. The continue statement is used to skip past the break. The try/except structure catches the error if it's not an integer, or the error explicitly raised if it's less than 0. It also uses the as feature of except to print a better indication of the error. It's encapsulated in a function to make things easier - I find factorial(get_input()) to be pretty expressive, with the added bonus of being more reusable.
This currently doesn't end when the user input is 0, as 0 is a perfectly valid input for factorial, although it should be easy enough to adapt to this with an if statement.
This program might be used like this:
Enter a positive integer> abc
invalid literal for int() with base 10: 'abc'
Enter a positive integer> 0.2
invalid literal for int() with base 10: '0.2'
Enter a positive integer> -5
not a positive integer
Enter a positive integer> 6
720
By the way, this code works according to EAFP - it just tries to convert to an integer, and handles failure. This is more idiomatic Python than first trying to determine if it could be an integer (LBYL).
If you're using Python 2, you'll need to change input to raw_input.
Check if input is positive integer check this link out along with the link provided by user #cricket_007 above. Combining those two information should get you in the right direction.
Try to think of it as an algorithm problem not as a Python problem, you may find a solution because in general every language has its functions and they all almost the same only with different name.
In python they are a function call isnumeric() and it returns true if every single character is a number or false if it's not.
str.isnumeric()
us it with a statement condition like if
if str.isnumeric()==true // so it's numeric
// what to do!!!!!
the best choice it to use while and if
while true
//read data as string
if str.isnumeric()==true
break; // this to break the while loop
hope this can help you

Sometimes get a ValueError from passing a float to int() method, but not always

Python newbie here. I've been messing around with flow control and have come across a situation I don't quite understand related to exceptions.
In the following code I want the user to enter an integer in a given range and, in the case of non-compliance, keep asking them until they give a valid value:
while True:
try:
x = int(raw_input("Pick an integer between 2 and 9. "))
except ValueError:
print "Please enter an integer!"
continue
else:
if 2 <= x <= 9:
print("Your number is {0}.").format(x)
break
else:
print "That's not between 2 and 9!"
continue
As far as I can tell, this code works exactly as I want it to. I've thrown every other type of input I can think of at it and it only lets you exit the loop when an integer from 2-9 is entered. Not even floats are accepted.
My question is, given that int() can be successfully called on floats,
>>> int(2.1)
2
why does this try/except construct raise the exception when the input is a float? If I run the code without the try/except statements and enter anything other than an integer, it throws an error and exits.
I'm running python 2.7 from windows powershell.
This is because raw_input returns a string.
Under the hood, when you call int, it actually calls an objects object.__int__() method. This is different from object to object.
For a float, this truncates a value (Rounds towards 0).
On a string, it tries to parse an int according to https://docs.python.org/3/reference/lexical_analysis.html#integer-literals (Which can't have a .).
The issue here is that you are calling int() on a string that could potentially contain a period. To fix this I would recommend you change the int() to float(). This should fix your problem
x = float(raw_input("Pick an integer between 2 and 9. "))
Not sure what version of Python you are using but if it is Python 3.0 or above you might want to carefully check the print statements in the following clips
except ValueError:
print "Please enter an integer!"
else:
print "That's not between 2 and 9!"
they are not formatted for 3.0 but will probably work ok if you use version 2.x
I think the other answers covered your original problem adequately so I will defer to them.. they know that area better than I.
Good Luck,
Poe

Why is it not possible to convert "1.7" to integer directly, without converting to float first?

When I type int("1.7") Python returns error (specifically, ValueError). I know that I can convert it to integer by int(float("1.7")). I would like to know why the first method returns error.
From the documentation:
If x is not a number or if base is given, then x must be a string or Unicode object representing an integer literal in radix base ...
Obviously, "1.7" does not represent an integer literal in radix base.
If you want to know why the python dev's decided to limit themselves to integer literals in radix base, there are a possible infinite number of reasons and you'd have to ask Guido et. al to know for sure. One guess would be ease of implementation + efficiency. You might think it would be easily for them to implement it as:
Interpret number as a float
truncate to an integer
Unfortunately, that doesn't work in python as integers can have arbitrary precision and floats cannot. Special casing big numbers could lead to inefficiency for the common case1.
Additionally, forcing you do to int(float(...)) has the additional benefit in clarity -- It makes it more obvious what the input string probably looks like which can help in debugging elsewhere. In fact, I might argue that even if int would accept strings like "1.7", it'd be better to write int(float("1.7")) anyway for the increased code clarity.
1Assuming some validation. Other languages skip this -- e.g. ruby will evaluate '1e6'.to_i and give you 1 since it stops parsing at the first non-integral character. Seems like that could lead to fun bugs to track down ...
We have a good, obvious idea of what "make an int out of this float" means because we think of a float as two parts and we can throw one of them away.
It's not so obvious when we have a string. Make this string into a float implies all kinds of subtle things about the contents of the string, and that is not the kind of thing a sane person wants to see in code where the value is not obvious.
So the short answer is: Python likes obvious things and discourages magic.
Here is a good description of why you cannot do this found in the python documentation.
https://docs.python.org/2/library/functions.html#int
If x is not a number or if base is given, then x must be a string or Unicode object representing an integer literal in radix base. Optionally, the literal can be preceded by + or - (with no space in between) and surrounded by whitespace. A base-n literal consists of the digits 0 to n-1, with a to z (or A to Z) having values 10 to 35. The default base is 10. The allowed values are 0 and 2-36. Base-2, -8, and -16 literals can be optionally prefixed with 0b/0B, 0o/0O/0, or 0x/0X, as with integer literals in code. Base 0 means to interpret the string exactly as an integer literal, so that the actual base is 2, 8, 10, or 16.
Basically to typecast to an integer from a string, the string must not contain a "."
Breaks backwards-compatibility. It is certainly possible, however this would be a terrible idea since it would break backwards-compatibility with the very old and well-established Python idiom of relying on a try...except ladder ("Easier to ask forgiveness than permission") to determine the type of the string's contents. This idiom has been around and used since at least Python 1.5, AFAIK; here are two citations: [1] [2]
s = "foo12.7"
#s = "-12.7"
#s = -12
try:
n = int(s) # or else throw an exception if non-integer...
print "Do integer stuff with", n
except ValueError:
try:
f = float(s) # or else throw an exception if non-float...
print "Do float stuff with", f
except ValueError:
print "Handle case for when s is neither float nor integer"
raise # if you want to reraise the exception
And another minor thing: it's not just about whether the number contains '.' Scientific notation, or arbitrary letters, could also break the int-ness of the string.
Examples: int("6e7") is not an integer (base-10). However int("6e7",16) =
1767 is an integer in base-16 (or any base>=15). But int("6e-7") is never an int.
(And if you expand the base to base-36, any legal alphanumeric string (or Unicode) can be interpreted as representing an integer, but doing that by default would generally be a terrible behavior, since "dog" or "cat" are unlikely to be references to integers).

Convert float to integer in Python - invalid literal error

How do I convert this number to an integer I can do simple math with?!
(eg. 10.5200 below.)
{"bid":["10.52000000","0.70824000"],"ask":["10.54000000","2.07336000"],"seq":2456916}
I get the following error, and it's driving me mental:
ValueError: invalid literal for int() with base 10: '10.52'
This is what I'm running:
bitfl = json.loads(bitfl)
bid = bitfl['bid']
ask = bitfl['ask']
bidd = bid[0] #edit - this is actually in, as it's a list
askk = ask[0]
print('diff: %i' % (int(bidd[0]) - int(askk[0])))
I don't know WHY it should be so difficult to just accept "10.52" as a string or float or unicode and just convert it to a normal, calculable integer!
Any help MUCH appreciated!
The problem is that you are trying to convert a string containing a non-integer to an integer.
The easiest/best solution is using int(float(yourstring))
Since you receive the data as JSON you should also consider requiring whatever client is providing the data not to use strings for non-string data.
Simply write int(float(bidd[0]))

Categories