Re: strings and ints consistency - isinstance

2016-09-22 Thread Steve D'Aprano
On Thu, 22 Sep 2016 11:40 pm, Sayth Renshaw wrote:

> True it failed, just actually happy to get it to fail or pass successfully
> on int input.

But it doesn't. It raises ValueError no matter what you enter.





-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: strings and ints consistency - isinstance

2016-09-22 Thread Larry Hudson via Python-list

On 09/22/2016 06:40 AM, Sayth Renshaw wrote:
[snip...]


True it failed, just actually happy to get it to fail or pass successfully on 
int input.

Just felt it was a clearer and more consistent approach to verifying input, 
then most of the varied and rather inconsistent approaches I have seen in 
trying to get this to work.

Half opt for try except the other half if else and then implement them largely 
differently. Every many and varied approach str2bool(), isalpha() using list 
with isinstance(var, [ int, str, bool]) etc.

Anyway back to the old drawing board.

Cheers

Sayth



IMHO...  This sort of thing deserves to be written as a separate function which can then be 
called anytime, anyplace.  This keeps your validation and repeated input in one place and is 
done automatically, and lets your main program simply assume the input is valid.


For example, here is the help message for the number input function I wrote for my personal 
utility library:


---
get_num(prmt, min_val=None, max_val=None, flt=False)

Get a number from the console

Parameters:
prmt:   The prompt to be used with the input function, required.
min_val:The minimum permissible value, or None if no minimum (the 
default)
max_val:The maximum permissible value, or None if no maximum (the 
default)
flt:If True, accepts and returns floats
If False, accepts and returns integers (the default)

Invalid input or out-of-range values are not accepted and a warning message
is displayed.  It will then repeat the input prompt for a new value.
---

Admittedly, this may be overkill for general use, but it IS very handy.  Even if it is overkill, 
it is still very easy to use.  Similar validated input functions are useful as well — such as a 
Yes/No function among others.


If you're interested, I could post the source for this version, but if you think of it as a 
generic function rather than for a specific situation, it is pretty straight-forward to write. 
something similar.


--
 -=- Larry -=-
--
https://mail.python.org/mailman/listinfo/python-list


Re: strings and ints consistency - isinstance

2016-09-22 Thread Sayth Renshaw

> > This ends being the code I can use to get it to work, seems clear and
> > pythonic, open to opinion on that :-)
> 
> Neither clear, nor Pythonic.

Sadly imo clearer than the many hack attempts on SO.

> 
> > answer = input("\t >> ")
> 
> Since input() returns a string in Python 3, this will always be a string.
> 
> 
> > if isinstance(int(answer), int) is True:
> 
> int(answer) will either succeed, or it will fail. If it fails, it will raise
> ValueError, and your code will fail with an exception.
> 
> If it succeeds, then it will return an int. Testing whether int(answer)
> returns an int is a waste of time -- it *always* returns an int, if it
> returns at all. So if it returns, it will return an int, isinstance() will
> always return True, and True is True. So your code will then
> 
> > raise ValueError("Ints aren't valid input")
> 
> Which means your code will ALWAYS raise ValueError:
> 
> if answer is a numeric string, like "123", then int() will succeed, the if
> block will run, and ValueError is raised;
> 
> but if answer is NOT a numeric string, like "abc", then int() will raise
> ValueError.
> 
> So we can replace your entire block of code with a single line:
> 
> raise ValueError
> 
> since that is the only result possible. The rest of your code is dead
> code -- it cannot be executed.
> 
> But if it could...
> 
> 
> > sys.exit()
> 
> It seems a bit harsh to exit the application just because the user types the
> wrong value. Shouldn't you try again, let them type another string?
> 
> 
> > elif isinstance(answer, str) is True:
> > print(v0 * t - 0.5 * g * t ** 2)
> 
> Since input() returns a string, answer is always a string, and isinstance()
> will always return True. So True is True will always evaluate to True, and
> the print statement with the mysterious formula will always print.
> 
> 
> > else:
> > print("Ok please ammend your entries")
> 

True it failed, just actually happy to get it to fail or pass successfully on 
int input.

Just felt it was a clearer and more consistent approach to verifying input, 
then most of the varied and rather inconsistent approaches I have seen in 
trying to get this to work.

Half opt for try except the other half if else and then implement them largely 
differently. Every many and varied approach str2bool(), isalpha() using list 
with isinstance(var, [ int, str, bool]) etc.

Anyway back to the old drawing board.

Cheers

Sayth
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: strings and ints consistency - isinstance

2016-09-22 Thread Gregory Ewing

On Wednesday, September 21, 2016 at 11:41:42 PM UTC-4, Sayth Renshaw wrote:


answer = input("\t >> ")
if isinstance(int(answer), int) is True:
   raise ValueError("Ints aren't valid input")


You seem to be trying to check that the user hasn't entered
an integer. But that's a backwards way of looking at it. If
the only valid inputs at that point are "y" or "n", then
you should check for those specifically:

   answer = input("\t >> ")
   if answer == "y":
  # do the "yes" thing
   elif answer == "n":
  # do the "no" thing
   else:
  # user entered something wrong

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: strings and ints consistency - isinstance

2016-09-22 Thread Steve D'Aprano
On Thu, 22 Sep 2016 01:41 pm, Sayth Renshaw wrote:

> This ends being the code I can use to get it to work, seems clear and
> pythonic, open to opinion on that :-)

Neither clear, nor Pythonic.


> answer = input("\t >> ")

Since input() returns a string in Python 3, this will always be a string.


> if isinstance(int(answer), int) is True:

int(answer) will either succeed, or it will fail. If it fails, it will raise
ValueError, and your code will fail with an exception.

If it succeeds, then it will return an int. Testing whether int(answer)
returns an int is a waste of time -- it *always* returns an int, if it
returns at all. So if it returns, it will return an int, isinstance() will
always return True, and True is True. So your code will then

> raise ValueError("Ints aren't valid input")

Which means your code will ALWAYS raise ValueError:

if answer is a numeric string, like "123", then int() will succeed, the if
block will run, and ValueError is raised;

but if answer is NOT a numeric string, like "abc", then int() will raise
ValueError.

So we can replace your entire block of code with a single line:

raise ValueError

since that is the only result possible. The rest of your code is dead
code -- it cannot be executed.

But if it could...


> sys.exit()

It seems a bit harsh to exit the application just because the user types the
wrong value. Shouldn't you try again, let them type another string?


> elif isinstance(answer, str) is True:
> print(v0 * t - 0.5 * g * t ** 2)

Since input() returns a string, answer is always a string, and isinstance()
will always return True. So True is True will always evaluate to True, and
the print statement with the mysterious formula will always print.


> else:
> print("Ok please ammend your entries")

That can never occur, since both the if... clause and the elif... clause
will always evaluate as True. So this is dead code.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: strings and ints consistency - isinstance

2016-09-22 Thread Ned Batchelder
On Wednesday, September 21, 2016 at 11:41:42 PM UTC-4, Sayth Renshaw wrote:
> This ends being the code I can use to get it to work, seems clear and 
> pythonic, open to opinion on that :-)
> 
> 
> answer = input("\t >> ")
> if isinstance(int(answer), int) is True:
> raise ValueError("Ints aren't valid input")
> sys.exit()
> elif isinstance(answer, str) is True:
> print(v0 * t - 0.5 * g * t ** 2)
> else:
> print("Ok please ammend your entries")
> 
> Cheers
> 
> Sayth

1) When checking for truth, there's very very rarely a need to use
"if x is True:".  Instead, just use "if x:"

2) "isinstance(int(answer), int)" will either be True, because the
int() call succeeded and produced an int, or the int() call will raise
an error.  Using it as a condition is baroque, and will never result
in the elif clause being tested.  So I'm not sure how your code is
ever printing the result of the calculation, or printing the
"amend" message.

Are you sure you've tested this code thoroughly?

--Ned.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: strings and ints consistency - isinstance

2016-09-22 Thread Lawrence D’Oliveiro
On Thursday, September 22, 2016 at 3:41:42 PM UTC+12, Sayth Renshaw wrote:
> if isinstance(int(answer), int) is True:

Not sure what the point of this is...
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: strings and ints consistency - isinstance

2016-09-21 Thread Sayth Renshaw
This ends being the code I can use to get it to work, seems clear and pythonic, 
open to opinion on that :-)


answer = input("\t >> ")
if isinstance(int(answer), int) is True:
raise ValueError("Ints aren't valid input")
sys.exit()
elif isinstance(answer, str) is True:
print(v0 * t - 0.5 * g * t ** 2)
else:
print("Ok please ammend your entries")

Cheers

Sayth
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: strings and ints consistency - isinstance

2016-09-21 Thread Sayth Renshaw
To answer all the good replies.

I adapted a simple vector example from the Springer book practical primer on 
science with python.

Having solved the actual problem I thought checking with the user they had the 
correct entries or would like to ammend them would be a good addition. This 
leads to the question Y or N response which isn't hard but if someone 
accidentally types 4, then you get where I got stuck can't test an int for 
ValueError if you expect a string. 

This was my code

import sys

v0 = float(input("What velocity would you like? "))
g = float(input("What gravity would you like? "))
t = float(input("What time decimal would you like? "))

print("""
We have the following inputs.
   v0 is %d
   g is  %d
   t is  %d
Is this correct? [Y/n]
""" % (v0, g, t))
while True:
try:
answer = input("\t >> ").isalpha()
print(v0 * t - 0.5 * g * t ** 2)
except ValueError as err:
print("Not a valid entry", err.args)
sys.exit()
finally:
print("would you like another?")
break

___

When I look at this SO question it splits the votes half choose try except the 
other conditional logic, neither are wrong but which is the more obvious python 
way. 
https://stackoverflow.com/questions/2020598/in-python-how-should-i-test-if-a-variable-is-none-true-or-false

___

I actually thought this would have resolved my issues and still returned error 
if ints entered however it still passes through.

answer = input("\t >> ")
if isinstance(answer, str) is True:
print(v0 * t - 0.5 * g * t ** 2)
elif int(answer) is True:
raise ValueError("Ints aren't valid input")
sys.exit()
else:
print("Ok please ammend your entries")

Thanks

Sayth
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: strings and ints consistency - isinstance

2016-09-21 Thread Steve D'Aprano
On Thu, 22 Sep 2016 12:26 am, Sayth Renshaw wrote:

> Hi
> 
> Trying to clarify why ints and strings arent treated the same.

Because ints and strings are different? :-)


> You can get a valuerror from trying to cast a non-int to an int as in
> int(3.0) however you cannot do a non string with str(a).

Now, that's incorrect. int(3.0) succeeds, it doesn't raise ValueError.

int([]) will raise TypeError.

int("hello world") will raise ValueError, because int() can convert strings,
but only strings with the right value. If the string has an invalid value,
you get a ValueError.

But str(a) should succeed for any object, any value. It should (in
principle) *always* succeed. (If it fails for some object, that object is
buggy.)


> Which means that you likely should use try and except to test if a user
> enters a non-int with valuerror. However as you can't str () and get a
> valuerror you use conditional logic with strings.

What sort of conditional logic do you think you will use to determine
whether or not str(x) will fail?

 
> Therefore to try and keep with pythons only one obvious way of doing
> things should i prefer conditional logic for all using isinstance?

No. There is no connection between the One Obvious Way principle and this.
The principle of One Obvious Way is a design principle that applies to
Python the language and its standard library. (You can also apply it to
your own libraries, because it is a good principle to use.) But it has no
connection to how you test for invalid arguments.

> That way regardless of input type my code flows the same and more
> explicitly states the intended type. Sayth

That is an over-generalisation.

Nobody should care if, in one part of your application, you test for error
conditions using try...except, and in a completely different part of your
application you use an explicit test using if. They are different parts of
code, and there is nothing wrong with them being different.

One Obvious Way does not mean "Only One Way". It means that there must be an
obvious way to solve the problem, not that all problems must be solved the
same way.

When converting arbitrary objects to ints, the obvious way is to try the
conversion and catch TypeError or ValueError if it fails. (And then what?
What will you do with the exception once you have caught it? How do you
recover from this? If you have no way to recover, you probably shouldn't
bother catching the exception.)

When converting arbitrary objects to strings, the obvious way is to assume
that it will succeed.

When dealing with operations that might fail, there are generally two ways
to handle it:

Look Before You Leap (an explicit test using if)

Easier to Ask Forgiveness than Permission (try...except)

https://docs.python.org/3/glossary.html#term-lbyl

https://docs.python.org/3/glossary.html#term-eafp

Use whichever is appropriate for the situation. There is no need to always
use one or the other.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: strings and ints consistency - isinstance

2016-09-21 Thread John Gordon
In  Sayth Renshaw 
 writes:

> Trying to clarify why ints and strings arent treated the same.

Because they are not the same.

> You can get a valuerror from trying to cast a non-int to an int as in
> int(3.0) however you cannot do a non string with str(a).

Anything you type can be represented as a string*.  The same is
not true for integers.

* Okay, python 2.7 does have some issues with Unicode.

-- 
John Gordon   A is for Amy, who fell down the stairs
gor...@panix.com  B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: strings and ints consistency - isinstance

2016-09-21 Thread Ned Batchelder
On Wednesday, September 21, 2016 at 10:27:15 AM UTC-4, Sayth Renshaw wrote:
> Hi
> 
> Trying to clarify why ints and strings arent treated the same.
> 
> You can get a valuerror from trying to cast a non-int to an int as in 
> int(3.0) however you cannot do a non string with str(a).
> 
> Which means that you likely should use try and except to test if a user 
> enters a non-int with valuerror. 
> However as you can't str () and get a valuerror you use conditional logic 
> with strings.
> 
> Therefore to try and keep with pythons only one obvious way of doing things 
> should i prefer conditional logic for all using isinstance?
> 
> That way regardless of input type my code flows the same and more explicitly 
> states the intended type.
> Sayth

How you do your check depends a lot on why you are checking, how strange a
value you expecting to be checking, and what you want to do if the value
isn't good for you.  Can you give us specifics of the check you are doing,
and the values you want to accept/reject, and the behavior you want on
rejection?

int() and str() are not casts, they are conversions, or constructors, and
they have different ideas of the kinds of things they can turn into ints
and strs.

One Python philosophy is to not check types just to reject values, but
instead to work with the value you are given. This gives the caller the
flexibility to provide a value of a type perhaps you didn't expect, but
which will work fine anyway.

--Ned.
-- 
https://mail.python.org/mailman/listinfo/python-list


strings and ints consistency - isinstance

2016-09-21 Thread Sayth Renshaw
Hi

Trying to clarify why ints and strings arent treated the same.

You can get a valuerror from trying to cast a non-int to an int as in int(3.0) 
however you cannot do a non string with str(a).

Which means that you likely should use try and except to test if a user enters 
a non-int with valuerror. 
However as you can't str () and get a valuerror you use conditional logic with 
strings.

Therefore to try and keep with pythons only one obvious way of doing things 
should i prefer conditional logic for all using isinstance?

That way regardless of input type my code flows the same and more explicitly 
states the intended type.
Sayth
-- 
https://mail.python.org/mailman/listinfo/python-list