Issue44866
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2021-08-08 17:49 by TheDoctor165, last changed 2022-04-11 14:59 by admin. This issue is now closed.
Files | ||||
---|---|---|---|---|
File name | Uploaded | Description | Edit | |
function_int_08Aug21.txt | TheDoctor165, 2021-08-08 17:49 | text in comment, not sure if I should have documented in comment or just attached a file |
Messages (6) | |||
---|---|---|---|
msg399224 - (view) | Author: John Joseph Morelli (TheDoctor165) | Date: 2021-08-08 17:49 | |
I first noticed this and reported it on the W3 Schools Tutorial, the section entitled "Add Two Numbers with User Input" There were many behaviors that I did not understand, but for this bug report, I will state that the input statements present seem to return a string and under most situations will return an error if the user inputs a real number like 2.8. However, under a very specific situation, it will truncate 2.8 to 2 without error. After further investigation, I believe the following session in the IDLE's output window and editor illustrates this inconsistent behavior. Note that I have added comments after copying the session here... >>> print(x) #want to ensure new session has x as undefined Traceback (most recent call last): File "<pyshell#23>", line 1, in <module> print(x) NameError: name 'x' is not defined # confirmed x is undefined >>> x="2" # define x as the string "2" >>> print(x) 2 >>> print(type(x)) # confirm that x is a string value of "2" <class 'str'> >>> y=int(x) # convert string value of "2" to integer of 2 - # according to documentation this should work - see "If x is not a # number or if base is given, then x must be a string, bytes, or # bytearray instance representing an integer literal in radix base." # at link --> https://docs.python.org/3.9/library/functions.html#int >>> print(type(y)) # ensure y is type int <class 'int'> >>> print(y) 2 >>> z=x+".8" # create z to be the concatenation of two strings "2" and ".8" = "2.8", a string representation of the real number 2.8 >>> print(z) 2.8 >>> print(type(z)) # ensure z is a string <class 'str'> >>> aa=int(z) # convert z to an integer (as descried in the link # above, this should NOT work Traceback (most recent call last): File "<pyshell#34>", line 1, in <module> aa=int(z) ValueError: invalid literal for int() with base 10: '2.8' >>> w="2.8" # Define w directly as the string value of 2.8 = "2.8" >>> bb=int(w) # This should also produce an error Traceback (most recent call last): File "<pyshell#36>", line 1, in <module> bb=int(w) ValueError: invalid literal for int() with base 10: '2.8' >>> a='2.8' >>> b=int(a) Traceback (most recent call last): File "<pyshell#38>", line 1, in <module> b=int(a) ValueError: invalid literal for int() with base 10: '2.8' >>> print(type(a)) # Ensure a is a string <class 'str'> >>> w="2" >>> bb=int(w) >>> print(bb) 2 >>> print(type(bb)) <class 'int'> >>> test=int(input("What is test value? ")) #lets try inputting a # real number but as an argument to int and assigning it to test What is test value? 2.8 # this should not work either Traceback (most recent call last): File "<pyshell#46>", line 1, in <module> test=int(input("What is test value? ")) ValueError: invalid literal for int() with base 10: '2.8' >>> # So everything here is working as expected, but... Here is code from the IDLE editor... a file called testinput1.py x = int(1) y = input("Type a number: ") print(type(y)) int_y = int(2.8) #conver y to an integer 2 and assign to int_y z = int("3") print(x) print(y) print(int_y) print(z) # I can find no documentation to suggest this should work, but it does. Here is the output in IDLE's shell Type a number: 2.8 <class 'str'> 1 2.8 2 3 Now, if I immediately go into the shell while the variables remain untouched and defined... >>> a=int(y) # Correctly, this produces the expected error Traceback (most recent call last): File "<pyshell#47>", line 1, in <module> a=int(y) ValueError: invalid literal for int() with base 10: '2.8' After extensive testing, I conclude that after input, you may immediately apply the int() function to the resulting string, but you quickly lose that ability, resulting in the expected error. I can find no documentation to explain this behavior. If I am not overlooking something, I think this should either be in the documentation of the function int(), if it is intended to behaviour this way, or as a bug, should be corrected. NOTE, I just started learning Pytyon this weekend, so I may be just ignorant of the behavior, but I have searched a good bit and found nothing suggesting this is how int() should behalf. I have also not studied the other constructor functions. |
|||
msg399225 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2021-08-08 18:03 | |
Following your long example, it seems to me that all works as you expected. Raise an exception if you expect exception, and does raise it if you expect no exception. I may miss something, what exactly does not work as you expected? |
|||
msg399229 - (view) | Author: Dennis Sweeney (Dennis Sweeney) * | Date: 2021-08-08 18:16 | |
You typed `int_y = int(2.8)`, so you passed the floating point number 2.8, which the int() function rounds down to 2. On the other hand when y had the string value '2.8'. The int(y) call tried to parse an integer out of the string, but failed since there were numbers after the decimal point. Passing a float rounds down: >>> int(2.8) 2 Passing a string with numbers after the decimal raises ValueError: >>> int('2.8') ValueError: invalid literal for int() with base 10: '2.8' Passing a string of digits without a decimal correctly parses an integer: >>> int('42') 42 Note that the input() function always returns a string, so input() can return '2.8', but not 2.8. |
|||
msg399232 - (view) | Author: Steven D'Aprano (steven.daprano) * | Date: 2021-08-08 19:02 | |
John, there's no need to establish every feature in Python that you are **not** questioning. Please focus on the behaviour that you think is a bug. Pretty much nothing in your example before the line "So everything here is working as expected" is necessary. We're experienced Python users, some of us have been using Python for 20 years or more. We know how int() operates, you don't have to teach us. What you have done is confuse the string '2.8' and the float 2.8, which is easy enough to do as a beginner. The critical error is this line: int_y = int(2.8) #conver y to an integer 2 and assign to int_y But that's not converting the variable `y` to an integer, it is converting the float 2.8 to an integer. 2.8 is already a number, and calling int(2.8) drops the fractional part leaving 2 as expected. Had you tried `int_y = int(y)` instead (y being a string) you would have got the exact error you were expecting. It takes a little while to completely understand the differences between strings, ints, floats, literal numbers like 2.8 versus strings like "2.8", but that will come with some practice. In future, rather than posting on the bug tracker, please consider asking questions on one of the many forums where volunteers will answer your questions and leave the bug tracker for actual bugs. (Hint: there are many tens of thousands of Python programmers with collectively thousands of years of experience with the language. As a beginner with only a few days experience, you are highly unlikely to spot a bug that everyone else has missed.) You can try the Python Discussion area: https://discuss.python.org/ or the Python-List or Tutor mailing lists: https://mail.python.org/mailman/listinfo/python-list https://mail.python.org/mailman/listinfo/tutor Good luck! |
|||
msg399233 - (view) | Author: Terry J. Reedy (terry.reedy) * | Date: 2021-08-08 19:11 | |
John, for next time, please read https://stackoverflow.com/help/minimal-reproducible-example |
|||
msg399236 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2021-08-08 19:31 | |
I understand your confusion John. The fact is that int() serves two functions. If argument is a number, it truncates it to an integer. If argument is a string, it parses the string representation of integer (not necessary decimal). For details see https://docs.python.org/3/library/functions.html#int . |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:59:48 | admin | set | github: 89029 |
2021-08-08 19:31:10 | serhiy.storchaka | set | messages: + msg399236 |
2021-08-08 19:11:50 | terry.reedy | set | messages: + msg399233 |
2021-08-08 19:03:53 | steven.daprano | set | status: open -> closed resolution: not a bug stage: resolved |
2021-08-08 19:02:33 | steven.daprano | set | nosy:
+ steven.daprano messages: + msg399232 |
2021-08-08 18:16:45 | Dennis Sweeney | set | nosy:
+ Dennis Sweeney messages: + msg399229 |
2021-08-08 18:03:36 | serhiy.storchaka | set | nosy:
+ serhiy.storchaka messages: + msg399225 |
2021-08-08 17:49:51 | TheDoctor165 | create |