Re: How to make argparse accept "-4^2+5.3*abs(-2-1)/2" string argument?

2023-01-22 Thread Michael Torrie
On 1/22/23 11:44, Stefan Ram wrote:
> Jach Feng  writes:
>> e:\Works\Python>py infix2postfix.py "-4^2+5.3*abs(-2-1)/2"
> 
>   Well, it's a nice exercise! But I only made it work for the
>   specific example given. I have not tested whether it always
>   works.

Haha.  Yes a nice exercise, but has nothing to do with the original
question which is how to convince argparse to accept a string like that
without thinking it's a switch.  Many unix utilities treat "--" as a
special argument that turns off argument parsing for the rest of the
command line. Maybe argparse follows this convention too; I don't know.
But if it did you'd do:

infix2postfix.py -- "-4^2+5.3*abs(-2-1)/2"
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to make argparse accept "-4^2+5.3*abs(-2-1)/2" string argument?

2023-01-22 Thread Cameron Simpson

On 21Jan2023 19:11, Jach Feng  wrote:

Fail on command line,

e:\Works\Python>py infix2postfix.py "-4^2+5.3*abs(-2-1)/2"
usage: infix2postfix.py [-h] [infix]
infix2postfix.py: error: unrecognized arguments: -4^2+5.3*abs(-2-1)/2


The usual convention for having "nonoption" arguments beginning with a 
dash/minus is to explicitly _end_ the option arguments, eg:


py infix2postfix.py -- "-4^2+5.3*abs(-2-1)/2"

That "--" indicates the end of the options, and that what follows should 
not be treated as an option. _However_, it requires support in the 
script parsing the options. I'm pretty sure argparse gives that support 
for free, as does getopt and probably any others implementing "normal 
UNIXish options".


SO try adding a "--" argument and see how it behaves.


Also fail in REPL,

e:\Works\Python>py
Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:08:11) [MSC v.1928 32 bit 
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.

import argparse
parser = argparse.ArgumentParser(description='Convert infix notation to 
postfix')
parser.parse_args("-4^2+5.3*abs(-2-1)/2")

usage: [-h]
: error: unrecognized arguments: - 4 ^ 2 + 5 . 3 * a b s ( - 2 - 1 ) / 2


This is a different error. `parse_args()` expects a list of arguments, 
not a single argument. So it has iterated over what you gave it, which 
produces a series of single character strings which it has taken to be 
individual arguments. Try this:


parser.parse_args(["-4^2+5.3*abs(-2-1)/2"])

and of course:

parser.parse_args(["--", "-4^2+5.3*abs(-2-1)/2"])

You can see this behaviour of strings as:

print(list("abc"))

or:

for s in "abc":
print("s =", repr(s))

Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: How to make argparse accept "-4^2+5.3*abs(-2-1)/2" string argument?

2023-01-22 Thread Weatherby,Gerard
Argparse is for parsing command line arguments and options.

If you just want to evaluate an Python expression, use eval( )

Your string isn’t valid Python due to order of operations, but 
-(4^2)+5.3*abs(-2-1)/2 is.

From: Python-list  on 
behalf of Jach Feng 
Date: Sunday, January 22, 2023 at 11:24 AM
To: python-list@python.org 
Subject: Re: How to make argparse accept "-4^2+5.3*abs(-2-1)/2" string argument?
*** Attention: This is an external email. Use caution responding, opening 
attachments or clicking on links. ***

Thomas Passin 在 2023年1月22日 星期日下午1:30:39 [UTC+8] 的信中寫道:
> On 1/21/2023 10:11 PM, Jach Feng wrote:
> > Fail on command line,
> >
> > e:\Works\Python>py infix2postfix.py "-4^2+5.3*abs(-2-1)/2"
> > usage: infix2postfix.py [-h] [infix]
> > infix2postfix.py: error: unrecognized arguments: -4^2+5.3*abs(-2-1)/2
> >
> > Also fail in REPL,
> >
> > e:\Works\Python>py
> > Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:08:11) [MSC v.1928 32 
> > bit (Intel)] on win32
> > Type "help", "copyright", "credits" or "license" for more information.
>  import argparse
>  parser = argparse.ArgumentParser(description='Convert infix notation to 
>  postfix')
>  parser.parse_args("-4^2+5.3*abs(-2-1)/2")
> > usage: [-h]
> > : error: unrecognized arguments: - 4 ^ 2 + 5 . 3 * a b s ( - 2 - 1 ) / 2
> >
> > Just can't figure out where is wrong!?
> It just doesn't work like that. If you download the package, there is
> only one python file, __init__.py. This file contains one class. It
> has a demo at the end, commented out. If you uncomment those lines and
> run the file, you get a result printed.
>
> These remarks are based on downloading the link for the source
> distribution from Pypi
> (https://urldefense.com/v3/__https://pypi.org/project/infix2postfix/__;!!Cn_UX_p3!gqKmYLlyUndAzxmJsqCB429izQ-2-KMbpGP2eVzp_iDKtbgQXfrCu21UBvepq-F9EXb4SJwP516MHeUFMBtW$
>  ). When I installed it with
> pip, nothing seems to have gotten installed although pip went through
> the motions and claimed it was. So I just downloaded the source package.
>
> The test expression is "-(a*b)+(c+d)-(a+b+c+d)". The test output for
> this is "ab*-cd++ab+c+d+-".
>
> If you substitute your expression, the result is
>
> abs1-2-*2/3.5+2^4-
>
> This may or may not be correct. I'm not sure but I think it's as
> intended except for reversing "3.5". But maybe that's right, I'm not
> too sure. Notice that this file is in its first release, version 0.0.1
> - the metadata that says it's 'Development Status :: 5 -
> Production/Stable' seems to be bogus. So it may very well be buggy.
>
> At any rate, if you want to use it in a program that can accept
> arguments, you will have to write that part yourself. And the
> expression you feed it would need to be a single string, meaning it has
> to be quoted on the command line as you have done (although on Windows
> you should be using double quotes instead of single quotes).
>
> As for argparse, it isn't doing what you want because you haven't told
> it what to do with the arguments.
Sorry to cause confusion here. I don't know there is a Pypi project with the 
same name infix2postfix.py:-(

Nevertheless, Is there anyway to make parse_args works?
>>> parser.parse_args("-4^2+5.3*abs(-2-1)/2")
--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!gqKmYLlyUndAzxmJsqCB429izQ-2-KMbpGP2eVzp_iDKtbgQXfrCu21UBvepq-F9EXb4SJwP516MHezHygV-$
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: tree representation of Python data

2023-01-22 Thread Thomas Passin

On 1/21/2023 10:03 AM, Dino wrote:


I have a question that is a bit of a shot in the dark. I have this nice 
bash utility installed:


$ tree -d unit/
unit/
├── mocks
├── plugins
│   ├── ast
│   ├── editor
│   ├── editor-autosuggest
│   ├── editor-metadata
│   ├── json-schema-validator
│   │   └── test-documents
│   └── validate-semantic
│   ├── 2and3
│   ├── bugs
│   └── oas3
└── standalone
     └── topbar-insert

I just thought that it would be great if there was a Python utility that 
visualized a similar graph for nested data structures.
Of course I am aware of indent (json.dumps()) and pprint, and they are 
OK options for my need. It's just that the compact, improved 
visualization would be nice to have. Not so nice that I would go out of 
my way to build, but nice enough to use an exising package.


It's not clear to me whether you want to display JSON structures or 
Python objects.  However, Python dictionaries are so similar to JSON 
structures that a dictionary example should be pretty close.


This can actually be a tricky problem because for complicated nesting, 
it's not that easy to work out how to display the elements.  The 
examples posted in this thread so far have been somewhat obscured by the 
use of leader lines, etc, so that it's a little hard to discern the 
simple core of the algorithm.


Below I include code that displays each leaf element on its own indented 
line, can only display keys and simple leaf values, and does not 
construct leader lines so as to keep the code easy to read.  In this 
form it can only display Python dictionaries but could be modified for 
JSON without too much work.


"""Display nested objects as an indented list."""
INDENT = ' ' * 3
DICT = {'a': {'aa':'AA', 'ab':'AB'},
'b': {'ba': {'baa': 'BAA', 'bab': 'BAB'},
  'bb':'BB'},
'c': ['CA', 'CB'],
'd': 'D' }
SIMPLE_TYPES = (int, float, str, bytes)

def unroll(obj, indent = ''):
if isinstance(obj, dict):
unroll_dict(obj, indent)
else:
"""unroll other kinds of objects (not implemented)."""
print(indent, 'Can only unroll nested dictionaries')

def unroll_dict(dct, indent = ''):
"""Unroll a dictionary whose values can be either simple or
   nested.
"""
for k, v in dct.items():
g.es(indent, k)
new_indent = indent + INDENT
if type(v) in SIMPLE_TYPES:
print(new_indent, v)
else:
unroll(v, new_indent)
# print(f'{new_indent}{v}')

unroll(DICT)

Output:
a
aa
   AA
ab
   AB
b
ba
   baa
  BAA
   bab
  BAB
bb
   BB
c
Can only unroll nested dictionaries
d
D

If you change the last else block, you can make use of the object's 
internal representation (not for JSON, of course).  Change the block to 
read:


# unroll(v, new_indent)
print(f'{new_indent}{v}')

This change gives the following output:

a
   {'aa': 'AA', 'ab': 'AB'}
b
   {'ba': {'baa': 'BAA', 'bab': 'BAB'}, 'bb': 'BB'}
c
   ['CA', 'CB']
d
D


In practice, I would collect the text fragments into a list instead of 
printing them, then print the joined list at the end.

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


Re: How to make argparse accept "-4^2+5.3*abs(-2-1)/2" string argument?

2023-01-22 Thread Thomas Passin

On 1/22/2023 10:45 AM, Peter J. Holzer wrote:

Notice that this file is in its first release, version 0.0.1 - the metadata
that says it's 'Development Status :: 5 - Production/Stable' seems to be
bogus.  So it may very well be buggy.

It is at least too incomplete to be useful. It handles only single
letters as operands and treats everything else (except parentheses) as an 
operator, handling
only +, -, *, / and ^ correctly (actually, ^ is typically right
associative, so that's arguably wrong, too).


This script is basically useless without some documentation on the 
intended inputs and outputs, and how to invoke it.  The documentation 
could (in the minimal case) have been included in docstrings and 
comments within the script.  As it is, the script seems tantalizing but 
unusable.


Please document your work, even if it's just for yourself!

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


Re: How to make argparse accept "-4^2+5.3*abs(-2-1)/2" string argument?

2023-01-22 Thread Mark Bourne

Jach Feng wrote:

Fail on command line,

e:\Works\Python>py infix2postfix.py "-4^2+5.3*abs(-2-1)/2"
usage: infix2postfix.py [-h] [infix]
infix2postfix.py: error: unrecognized arguments: -4^2+5.3*abs(-2-1)/2

Also fail in REPL,

e:\Works\Python>py
Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:08:11) [MSC v.1928 32 bit 
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.

import argparse
parser = argparse.ArgumentParser(description='Convert infix notation to 
postfix')
parser.parse_args("-4^2+5.3*abs(-2-1)/2")

usage: [-h]
: error: unrecognized arguments: - 4 ^ 2 + 5 . 3 * a b s ( - 2 - 1 ) / 2

Just can't figure out where is wrong!?


First, you need to add an argument to the parser, so that it expects an 
argument:

>>> parser.add_argument("expression")

Secondly, `parse_args` expects a list of arguments.  By passing a 
string, it interprets each character as a separate argument (since 
iterating over a string yields each character in turn).  Here, I 
intentionally leave off the initial hyphen because that's the next problem:

>>> parser.parse_args(["4^2+5.3*abs(-2-1)/2"])
Namespace(expression='4^2+5.3*abs(-2-1)/2')

Thirdly, an initial hyphen indicates an optional argument so, for 
example if you pass "-l" it will expect a "-l" argument to be defined as 
one of the valid options, and also complain that you haven't specified 
the required expression:

>>> parser.parse_args(["-4^2+5.3*abs(-2-1)/2"])
usage: [-h] expression
: error: the following arguments are required: expression

If you need to pass a value starting with a "-" there are a couple of 
options...


Perhaps it would be acceptable to represent it as "0-...":
>>> parser.parse_args(["0-4^2+5.3*abs(-2-1)/2"])
Namespace(expression='0-4^2+5.3*abs(-2-1)/2')

While mathematically equivalent, that might have different meaning for 
whatever you're trying to do.  Alternatively, a double hyphen indicates 
that there are no more options and that anything else is positional 
arguments even if they begin with a hyphen:

>>> parser.parse_args(["--", "-4^2+5.3*abs(-2-1)/2"])
Namespace(expression='-4^2+5.3*abs(-2-1)/2')

You wouldn't usually explicitly pass a list of arguments to `parse_args` 
like that, but it can be useful for testing and experimentation. 
Usually, you'd call `parse_args()` without any arguments, and it would 
parse the arguments passed on the command-line when calling your script. 
 e.g. you'd call (from a Windows command prompt / Linux shell / etc.):

> ./convert_infix.py -- '-4^2+5.3*abs(-2-1)/2'
(it's probably a good idea to quote the expression, in case it includes 
any characters which would be interpreted specially by the shell - e.g. 
"*" without quotes usually expands to all matching files in the current 
directory)


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


Re: How to make argparse accept "-4^2+5.3*abs(-2-1)/2" string argument?

2023-01-22 Thread Jach Feng
Thomas Passin 在 2023年1月22日 星期日下午1:30:39 [UTC+8] 的信中寫道:
> On 1/21/2023 10:11 PM, Jach Feng wrote: 
> > Fail on command line, 
> > 
> > e:\Works\Python>py infix2postfix.py "-4^2+5.3*abs(-2-1)/2" 
> > usage: infix2postfix.py [-h] [infix] 
> > infix2postfix.py: error: unrecognized arguments: -4^2+5.3*abs(-2-1)/2 
> > 
> > Also fail in REPL, 
> > 
> > e:\Works\Python>py 
> > Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:08:11) [MSC v.1928 32 
> > bit (Intel)] on win32 
> > Type "help", "copyright", "credits" or "license" for more information. 
>  import argparse 
>  parser = argparse.ArgumentParser(description='Convert infix notation to 
>  postfix') 
>  parser.parse_args("-4^2+5.3*abs(-2-1)/2") 
> > usage: [-h] 
> > : error: unrecognized arguments: - 4 ^ 2 + 5 . 3 * a b s ( - 2 - 1 ) / 2 
> > 
> > Just can't figure out where is wrong!?
> It just doesn't work like that. If you download the package, there is 
> only one python file, __init__.py. This file contains one class. It 
> has a demo at the end, commented out. If you uncomment those lines and 
> run the file, you get a result printed. 
> 
> These remarks are based on downloading the link for the source 
> distribution from Pypi 
> (https://pypi.org/project/infix2postfix/). When I installed it with 
> pip, nothing seems to have gotten installed although pip went through 
> the motions and claimed it was. So I just downloaded the source package. 
> 
> The test expression is "-(a*b)+(c+d)-(a+b+c+d)". The test output for 
> this is "ab*-cd++ab+c+d+-". 
> 
> If you substitute your expression, the result is 
> 
> abs1-2-*2/3.5+2^4- 
> 
> This may or may not be correct. I'm not sure but I think it's as 
> intended except for reversing "3.5". But maybe that's right, I'm not 
> too sure. Notice that this file is in its first release, version 0.0.1 
> - the metadata that says it's 'Development Status :: 5 - 
> Production/Stable' seems to be bogus. So it may very well be buggy. 
> 
> At any rate, if you want to use it in a program that can accept 
> arguments, you will have to write that part yourself. And the 
> expression you feed it would need to be a single string, meaning it has 
> to be quoted on the command line as you have done (although on Windows 
> you should be using double quotes instead of single quotes). 
> 
> As for argparse, it isn't doing what you want because you haven't told 
> it what to do with the arguments.
Sorry to cause confusion here. I don't know there is a Pypi project with the 
same name infix2postfix.py:-(

Nevertheless, Is there anyway to make parse_args works?
>>> parser.parse_args("-4^2+5.3*abs(-2-1)/2")
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to make argparse accept "-4^2+5.3*abs(-2-1)/2" string argument?

2023-01-22 Thread Peter J. Holzer
On 2023-01-22 00:30:07 -0500, Thomas Passin wrote:
> On 1/21/2023 10:11 PM, Jach Feng wrote:
> > e:\Works\Python>py infix2postfix.py "-4^2+5.3*abs(-2-1)/2"
> > usage: infix2postfix.py [-h] [infix]
> > infix2postfix.py: error: unrecognized arguments: -4^2+5.3*abs(-2-1)/2
[...]
> > > > > import argparse
> > > > > parser = argparse.ArgumentParser(description='Convert infix notation 
> > > > > to postfix')
> > > > > parser.parse_args("-4^2+5.3*abs(-2-1)/2")
> > usage: [-h]
> > : error: unrecognized arguments: - 4 ^ 2 + 5 . 3 * a b s ( - 2 - 1 ) / 2
> > 
> > Just can't figure out where is wrong!?
> 
> It just doesn't work like that.
[...]
> If you substitute your expression, the result is
> 
> abs1-2-*2/3.5+2^4-
> 
> This may or may not be correct. I'm not sure but I think it's as intended
> except for reversing "3.5".  But maybe that's right, I'm not too sure.

It depends on the intended meaning. But I'm pretty sure that "5.3" is
supposed to be a floating point number and not (5 operatordot 3), so
it's wrong to split that apart. (Also it seems that the code treats
digits as operators, not operands?)

Also "abs(...)" is almost certainly intended to be a function call, so
it should be invoked after its parameters.

I think the correct output (using newlines as delimiters) would be:

-4
2
^
5.3
-2
1
-
abs
*
2
/
+

> Notice that this file is in its first release, version 0.0.1 - the metadata
> that says it's 'Development Status :: 5 - Production/Stable' seems to be
> bogus.  So it may very well be buggy.

It is at least too incomplete to be useful. It handles only single
letters as operands and treats everything else (except parentheses) as an 
operator, handling
only +, -, *, / and ^ correctly (actually, ^ is typically right
associative, so that's arguably wrong, too).

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list