Re: [Tutor] Python-list thread: int vs. float
On Sat, Feb 11, 2017 at 8:53 PM, boB Stepp wrote: > > I suspect Eryk had set a normal 's' as an identifier for the character > code sequence that produces the non-ASCII output, but forgot to show > us that step. But I could be mistaken. Sorry, I forgot to show the assignment of the string "௧꘢୩" to the variable s. > Today I am working in Windows 7, not Linux Mint. Of course when I > attempted to copy and paste the non-ASCII sequence from Gmail into > cmd.exe I got 3 rectangular boxes on the paste line, indicating > cmd.exe could not translate those characters. If you're running python.exe, it either inherits or allocates a console, which is hosted by an instance of conhost.exe. At most you're inheriting a console from cmd.exe. That's the extent of its involvement. Think of conhost.exe as a terminal window, like GNOME Terminal, etc. cmd.exe and powershell.exe are shells that use standard I/O, much like Python's REPL -- or like running bash in a Unix terminal. The console window can handle characters in the basic multilingual plane (BMP). Python 3.6 uses the console's wide-character (Unicode) API, so it should have no problem reading the string "௧꘢୩" if typed or pasted into the console. For example, if it's assigned to `s`, then ascii(s) should show the correct \u literals: >>> ascii(s) "'\\u0be7\\ua622\\u0b69'" Unfortunately, for rendering text the Windows console has limited font support. It requires a strictly monospace font, among other criteria. It won't switch automatically to other fonts when the current font doesn't have a glyph for a character. It just displays an empty box glyph. In Windows 7 a good font choice for the console window is Consolas. It has pretty good coverage for Western languages, but not for any of the characters in "௧꘢୩". If you copy the empty-box glyphs from the console window to the clipboard, it's actually copying the Unicode characters, which can be pasted into a window that has better font support, such as notepad. So in 3.6 this is just a superficial rendering issue that can be addressed by using programs such as ConEmu that replace the standard console window (it hides the console and hooks the API to write to its own window). ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python-list thread: int vs. float
On Sat, Feb 11, 2017 at 7:08 PM, Steven D'Aprano wrote: > On Sat, Feb 11, 2017 at 02:28:42PM -0600, boB Stepp wrote: > >> Back in the main Python list thread, Marko Rauhamaa suggested >> (https://mail.python.org/pipermail/python-list/2017-February/719322.html): >> >> " >> ... >> Haven't been following the discussion, but this should be simply: >> >>ast.literal_eval("...") >> ... >> " >> >> This looks like it may do the trick quite concisely: > > Nope. Not even close. The problem is that you have to accept ints and > floats, but reject anything else, and literal_eval does not do that. > > py> import ast > py> ast.literal_eval('[1, {}, None, "s", 2.4j, ()]') > [1, {}, None, 's', 2.4j, ()] My intent was to follow up with type(ast.literal_eval(string_input_from_user)) and if that does not come out 'int' or 'float', then it can be rejected as invalid input from the user. In your example type() would return a list, which would be invalid input for the OP's case. Of course this seems like swatting a gnat with a sledge hammer, but it still seems that the combination of checking the return of type(ast.literal_eval(user_input)) does the job since everything that is not float or int can be rejected as invalid input, and the float case can get its special error message. Or am I missing something? boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python-list thread: int vs. float
On Sat, Feb 11, 2017 at 09:10:04AM -0800, Alex Kleider wrote: > What your 's' represents seems quite different to 'mine.' > There must be something else going on. > ??? I think there's an easy explanation for that, which is that eryksun probably just created a variable "s" but didn't show the code for that. Unfortunately copying and pasting Unicode characters from email to the Python interpreter may not always work, as that depends on how well at least four software components deal with Unicode: - the email program - the copy/paste clipboard manager - the console/terminal - the Python interpreter The second last one is particularly problematic under Windows. When clarity is more important than brevity, the best way to insert Unicode characters into a string is to use the '\N{name}' form: s = '\N{TAMIL DIGIT ONE}\N{VAI DIGIT TWO}\N{ORIYA DIGIT THREE}' Since that's pure ASCII, you can copy and paste it easily even in the most poorly-configured system. > Also of interest (at least to me) was the 'magic' you demonstrated in > the print function parameter list; my efforts to figure it out: > >>>word = "Hello" > >>>print((c for c in word)) > at 0xb71d125c> > >>>print(*(c for c in word)) > H e l l o > >>>print(*(c for c in word), sep='') > Hello Indeed: the leading * is just the systax for argument unpacking. If you have a sequence: seq = [1, 2, 3, 4] and unpack it: print(*seq) then what the print function sees is: print(1, 2, 3, 4) It works with any iterable, not just lists or tuples: also strings, generator expressions, and more. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python-list thread: int vs. float
On Sat, Feb 11, 2017 at 02:28:42PM -0600, boB Stepp wrote: > Back in the main Python list thread, Marko Rauhamaa suggested > (https://mail.python.org/pipermail/python-list/2017-February/719322.html): > > " > ... > Haven't been following the discussion, but this should be simply: > >ast.literal_eval("...") > ... > " > > This looks like it may do the trick quite concisely: Nope. Not even close. The problem is that you have to accept ints and floats, but reject anything else, and literal_eval does not do that. py> import ast py> ast.literal_eval('[1, {}, None, "s", 2.4j, ()]') [1, {}, None, 's', 2.4j, ()] literal_eval will parse and evaluate anything that looks like one of: - int - float - string - bool (True or False) - None - complex (e.g. -3.5+4.5j) - tuple - list - dict - set so it does *far* more than what the OP requires. [...] > That statement about potentially changing with each Python release > bothers me. Should I be bothered? No. In this case, you are parsing a string, and the ast module itself parses it to an Abstract Syntax Tree before evaluating literals, so it doesn't matter if the AST is different from one version to the next. You should only care if you generated an AST in (say) Python 3.5, saved it in a data file, then read it back in to Python 3.6 and tried to evaluate it. That may not succeed. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python-list thread: int vs. float
On Sat, Feb 11, 2017 at 2:06 AM, Steven D'Aprano wrote: > On Fri, Feb 10, 2017 at 07:59:04PM -0600, boB Stepp wrote: > >> He cannot figure out how to reliably tell if the user's input is an >> integer, float or neither. So I thought I would come up with my >> solution, which currently is: >> >> py3: def ck_input(): >> ... value_to_ck = input('Enter a number:') >> ... try: >> ... value = int(value_to_ck) >> ... print('You have entered an integer.') >> ... except ValueError: >> ... try: >> ... value = float(value_to_ck) >> ... print('You have entered a float.') >> ... except ValueError: >> ... print('You have failed to enter a numerical value.') >> ... > The only not-so-good part of this is that you have mixed user-interface > and internal calculation. Better: > > > def to_number(string): > """Convert string to either an int or a float, or raise ValueError.""" > try: > return int(string) > except ValueError: > return float(string) > > > def check_input(): > value_to_ck = input('Enter a number: ') > try: > value = to_number(value_to_ck) > except ValueError: > print('You have failed to enter a numerical value.') > return > if isinstance(value, float): > print('You have entered a float.') > else: > print('You have entered an int.') > > > This gives you nice separation between the function that interacts with > the user, and the function that does the actual conversion. Ah! I am glad I asked the questions. There is a difference between intellectually understanding what I should do and reliably implementing it in my regular coding practice. This is one such instance, probably of many unfortunately. I knew something was bothering me about this. I did not like nesting try...except two-deep. Now that you have shown the way, I see what was nagging at me. Thanks, Steve! boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python-list thread: int vs. float
On Sat, Feb 11, 2017 at 11:10 AM, Alex Kleider wrote: > On 2017-02-11 00:36, eryk sun wrote: >> >> Note that Python 3 uses the Unicode database to determine the decimal >> value of characters, if any. It's not limited to the ASCII decimal >> digits 0-9. For example: >> >> >>> s >> '௧꘢୩' >> >>> int(s) >> 123 >> >>> print(*(unicodedata.name(c) for c in s), sep='\n') >> TAMIL DIGIT ONE >> VAI DIGIT TWO >> ORIYA DIGIT THREE > > > ??? > alex@X301n3:~$ python3 > Python 3.4.3 (default, Nov 17 2016, 01:11:57) > [GCC 4.8.4] on linux > Type "help", "copyright", "credits" or "license" for more information. s > > Traceback (most recent call last): > File "", line 1, in > NameError: name 's' is not defined > What your 's' represents seems quite different to 'mine.' > There must be something else going on. I suspect Eryk had set a normal 's' as an identifier for the character code sequence that produces the non-ASCII output, but forgot to show us that step. But I could be mistaken. Today I am working in Windows 7, not Linux Mint. Of course when I attempted to copy and paste the non-ASCII sequence from Gmail into cmd.exe I got 3 rectangular boxes on the paste line, indicating cmd.exe could not translate those characters. However, if I paste them into IDLE or gvim, things are translated correctly: Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32 Type "copyright", "credits" or "license()" for more information. >>> s Traceback (most recent call last): File "", line 1, in s NameError: name 's' is not defined >>> '௧꘢୩' '௧꘢୩' >>> I think that this demonstrates that 's' is just an identifier pointing to the non-ASCII character sequence, but that the actual characters can be copied and pasted *if* the editor or environment you paste those characters into is setup to translate those characters. boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python-list thread: int vs. float
On Sat, Feb 11, 2017 at 11:10 AM, Alex Kleider wrote: > Also of interest (at least to me) was the 'magic' you demonstrated in the > print function parameter list; my efforts to figure it out: Isn't this just argument unpacking? Thus the necessary "*". word = "Hello" print((c for c in word)) Need print(*(c...)) to unpack the sequence arguments. > at 0xb71d125c> print(*(c for c in word)) > > H e l l o Spaces because of the default setting for sep argument for print() as you demonstrate next. print(*(c for c in word), sep='') > > Hello -- boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python-list thread: int vs. float
On Fri, Feb 10, 2017 at 7:59 PM, boB Stepp wrote: > I have been following the thread "int vs. float" > (https://mail.python.org/pipermail/python-list/2017-February/719287.html) > on the main list. A search for the OP on the Tutor archive came up > negative, so I am hoping he is not following Tutor tonight (Or anytime > prior to the due date for his homework!). The central part of > adam14711993's question is: > > "What I cannot figure out is how to write it so that if my user input > is, for example, 1.5, the program will result with: Sorry, you can > only order whole packages. > > "I understand that because I am starting out by assigning my > number_purchases_str to be an int, when the user enters a float that > is a conflict and will crash." > > He cannot figure out how to reliably tell if the user's input is an > integer, float or neither. Back in the main Python list thread, Marko Rauhamaa suggested (https://mail.python.org/pipermail/python-list/2017-February/719322.html): " ... Haven't been following the discussion, but this should be simply: ast.literal_eval("...") ... " This looks like it may do the trick quite concisely: py3: import ast py3: ast.literal_eval('5') 5 py3: ast.literal_eval('5.0') 5.0 py3: type(ast.literal_eval('5')) py3: type(ast.literal_eval('5.0')) It appears to reliably parse string input as to whether it is an integer or float. However, if the input is a non-numerical string: py3: ast.literal_eval('a') Traceback (most recent call last): File "", line 1, in File "C:\Program Files\Python35\lib\ast.py", line 84, in literal_eval return _convert(node_or_string) File "C:\Program Files\Python35\lib\ast.py", line 83, in _convert raise ValueError('malformed node or string: ' + repr(node)) ValueError: malformed node or string: <_ast.Name object at 0x02C9D860> But that seems okay, as in the OP's original problem spec, he just needed a way to determine integer, float or other non-acceptable input. This seems to do this quite directly. I am not familiar with "abstract syntax trees" (Python has so much very interesting stuff!). I am concerned about this paragraph at the beginning of the docs on it (https://docs.python.org/3/library/ast.html?highlight=ast.literal_eval#module-ast): "The ast module helps Python applications to process trees of the Python abstract syntax grammar. The abstract syntax itself might change with each Python release; this module helps to find out programmatically what the current grammar looks like." That statement about potentially changing with each Python release bothers me. Should I be bothered? The link to ast.literal_eval(): https://docs.python.org/3/library/ast.html?highlight=ast.literal_eval#ast.literal_eval What are the gotchas or other negatives from this approach? boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python-list thread: int vs. float
On 2017-02-11 00:36, eryk sun wrote: On Sat, Feb 11, 2017 at 8:06 AM, Steven D'Aprano wrote: Valid digits for integers include 0 through 9 in decimal Note that Python 3 uses the Unicode database to determine the decimal value of characters, if any. It's not limited to the ASCII decimal digits 0-9. For example: >>> s '௧꘢୩' >>> int(s) 123 >>> print(*(unicodedata.name(c) for c in s), sep='\n') TAMIL DIGIT ONE VAI DIGIT TWO ORIYA DIGIT THREE ??? alex@X301n3:~$ python3 Python 3.4.3 (default, Nov 17 2016, 01:11:57) [GCC 4.8.4] on linux Type "help", "copyright", "credits" or "license" for more information. s Traceback (most recent call last): File "", line 1, in NameError: name 's' is not defined What your 's' represents seems quite different to 'mine.' There must be something else going on. ??? Also of interest (at least to me) was the 'magic' you demonstrated in the print function parameter list; my efforts to figure it out: word = "Hello" print((c for c in word)) at 0xb71d125c> print(*(c for c in word)) H e l l o print(*(c for c in word), sep='') Hello ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python-list thread: int vs. float
On Sat, Feb 11, 2017 at 8:06 AM, Steven D'Aprano wrote: > Valid digits for integers include 0 through 9 in decimal Note that Python 3 uses the Unicode database to determine the decimal value of characters, if any. It's not limited to the ASCII decimal digits 0-9. For example: >>> s '௧꘢୩' >>> int(s) 123 >>> print(*(unicodedata.name(c) for c in s), sep='\n') TAMIL DIGIT ONE VAI DIGIT TWO ORIYA DIGIT THREE ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python-list thread: int vs. float
On Fri, Feb 10, 2017 at 07:59:04PM -0600, boB Stepp wrote: > He cannot figure out how to reliably tell if the user's input is an > integer, float or neither. So I thought I would come up with my > solution, which currently is: > > py3: def ck_input(): > ... value_to_ck = input('Enter a number:') > ... try: > ... value = int(value_to_ck) > ... print('You have entered an integer.') > ... except ValueError: > ... try: > ... value = float(value_to_ck) > ... print('You have entered a float.') > ... except ValueError: > ... print('You have failed to enter a numerical value.') > ... [...] > This is all well and good. I am not trying to elicit an "Atta boy, > boB!" here. ~(:>)) Nevertheless, atta boy boB! The only not-so-good part of this is that you have mixed user-interface and internal calculation. Better: def to_number(string): """Convert string to either an int or a float, or raise ValueError.""" try: return int(string) except ValueError: return float(string) def check_input(): value_to_ck = input('Enter a number: ') try: value = to_number(value_to_ck) except ValueError: print('You have failed to enter a numerical value.') return if isinstance(value, float): print('You have entered a float.') else: print('You have entered an int.') This gives you nice separation between the function that interacts with the user, and the function that does the actual conversion. > Instead, I am wondering if there is something in > Python's wonderful cornucopia of programming stuff that can simplify > this type of check. The most reliable and foolproof way of checking if something is a valid int is to ask int to convert it, and see if it fails. Likewise for floats, where the format is *very* complex. Any of these, and many more, should be accepted: 1.2345 +1.2345 -1.2345e0 123.45e+20 123.45E-20 .123 -.123 +.123e-12 123. inf +inf -inf NaN Getting all the gory details right of what is and isn't allowed may be tricky, but that's okay, because float() already understands how to do it for you. > As you might guess from my earlier post this > evening, I have been playing around with "type()" and "isinstance()", > but if I try something like: > > py3: isinstance(int('5.0')) > Traceback (most recent call last): > File "", line 1, in > ValueError: invalid literal for int() with base 10: '5.0' The problem here is that int('5.0') raises an exception because '.' is not a valid digit for integers, so it fails before isinstance() gets a chance to run. Valid digits for integers include 0 through 9 in decimal, plus no more than one leading + or - sign, and whitespace (space, tabs, newlines) before or after the string. If you specify the base, the set of valid digits will change, e.g. int(string, 16) will allow 0 through 9 plus A through F in lower and upper case. But whatever base you choose, '.' is not a valid digit. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Python-list thread: int vs. float
I have been following the thread "int vs. float" (https://mail.python.org/pipermail/python-list/2017-February/719287.html) on the main list. A search for the OP on the Tutor archive came up negative, so I am hoping he is not following Tutor tonight (Or anytime prior to the due date for his homework!). The central part of adam14711993's question is: "What I cannot figure out is how to write it so that if my user input is, for example, 1.5, the program will result with: Sorry, you can only order whole packages. "I understand that because I am starting out by assigning my number_purchases_str to be an int, when the user enters a float that is a conflict and will crash." He cannot figure out how to reliably tell if the user's input is an integer, float or neither. So I thought I would come up with my solution, which currently is: py3: def ck_input(): ... value_to_ck = input('Enter a number:') ... try: ... value = int(value_to_ck) ... print('You have entered an integer.') ... except ValueError: ... try: ... value = float(value_to_ck) ... print('You have entered a float.') ... except ValueError: ... print('You have failed to enter a numerical value.') ... (Yes, I know I am not doing anything with the variable, "value", but if I were to actually implement this in the future, I am sure I would find a use for it. So I left it as is for the moment.) My quick checks are: py3: ck_input() Enter a number:5 You have entered an integer. py3: ck_input() Enter a number:5.0 You have entered a float. py3: ck_input() Enter a number:'5' You have failed to enter a numerical value. This is all well and good. I am not trying to elicit an "Atta boy, boB!" here. ~(:>)) Instead, I am wondering if there is something in Python's wonderful cornucopia of programming stuff that can simplify this type of check. As you might guess from my earlier post this evening, I have been playing around with "type()" and "isinstance()", but if I try something like: py3: isinstance(int('5.0')) Traceback (most recent call last): File "", line 1, in ValueError: invalid literal for int() with base 10: '5.0' I get the ValueError I make use of in my function above. So, is there any easier way to do this check? If not, can my function be improved to make it a bit less lengthy, but still eminently readable? TIA! -- boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor