Re: [Tutor] python-files

2019-01-27 Thread Alan Gauld via Tutor
On 27/01/2019 14:57, Asad wrote:

> print("first:", args.first)
> print("second:", args.second)
> 
> When I execute the script it gives error :
> 
> python python_json_20001_oratest_v1.py "file1"
> ('first:', 'file1')
> ('second:', None)

Note that the second file is None.

> Traceback (most recent call last):
>   File "test.py", line 211, in 
> with open(args.second, 'r') as f :
> TypeError: coercing to Unicode: need string or buffer, NoneType found

Note that you get a TypeError because you passed None instead
of a valid filename.

> try :
> with open(args.second, 'r') as f :
>  for line in f:
> print line
> except IOError:
>  print "The default error is err-1 because file2 was not provided "

Note that you are trying to catch an IOError but you are getting a
TypeError. You need to add another except clause for the TypeError.
Or test for a None second file value at the start of your code...

> Does that mean my try and except block is not working because if
> args.second  is None as in this case then it should print "The default
> error is err-1 because file2 was not provided "

It is working. You just aren't catching the correct error type.
It will only type the message you've given if you get an
IOError, but the open() code isn't getting that far,
it's failing on the parameter type.

> Please advice ,

OK, I advise you to delete the text below where you no longer
need it. Some users pay by the byte and all this excess text
costs them money. More than 75% of your message is included
text that we have already seen.

> Thanks,
> 
> 
>> -- Forwarded message --
>> From: Peter Otten <__pete...@web.de>
>> To: tutor@python.org
...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] python-files

2019-01-27 Thread Peter Otten
Asad wrote:

> Hi All ,
> 
>   I tried the following code  :
> 
> parser = argparse.ArgumentParser()
> parser.add_argument("first")
> parser.add_argument("second", nargs="?")
> args = parser.parse_args()
> print("first:", args.first)
> 
> print("second:", args.second)
> 
> When I execute the script it gives error :
> 
> python python_json_20001_oratest_v1.py "file1"
> ('first:', 'file1')
> ('second:', None)
> Traceback (most recent call last):
>   File "test.py", line 211, in 
> with open(args.second, 'r') as f :
> TypeError: coercing to Unicode: need string or buffer, NoneType found
> 
> 
> if I see in line number 211 it with open(args.second, 'r') as f :
> 
> try :
> with open(args.second, 'r') as f :
>  for line in f:
> print line
> except IOError:
>  print "The default error is err-1 because file2 was not provided
>  "

How do you know that the file was not provided? The name might have been 
misspelt or the user lacks the permission to read it.

> Does that mean my try and except block is not working because if
> args.second  is None as in this case then it should print "The default
> error is err-1 because file2 was not provided "
> 
> Please advice ,

If you just want to terminate the script with a helpful message you should 
make the second argument mandatory, too:

parser = argparse.ArgumentParser()
parser.add_argument("first")
parser.add_argument("second")
args = parser.parse_args()

That way the parse_args() call will terminate the script and the user will 
see an error message immediately.

If for some reason you want to keep the argument optional you can check for 
None before trying to open the file:

if args.second is not None:
try:
with open(args.second, 'r') as f :
for line in f:
print line
except IOError as err:
print err  # print actually what happened, not what you guess
else:
print "File 'second' was not provided on the command line"



___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] python-files

2019-01-27 Thread Asad
Hi All ,

  I tried the following code  :

parser = argparse.ArgumentParser()
parser.add_argument("first")
parser.add_argument("second", nargs="?")
args = parser.parse_args()
print("first:", args.first)

print("second:", args.second)

When I execute the script it gives error :

python python_json_20001_oratest_v1.py "file1"
('first:', 'file1')
('second:', None)
Traceback (most recent call last):
  File "test.py", line 211, in 
with open(args.second, 'r') as f :
TypeError: coercing to Unicode: need string or buffer, NoneType found


if I see in line number 211 it with open(args.second, 'r') as f :

try :
with open(args.second, 'r') as f :
 for line in f:
print line
except IOError:
 print "The default error is err-1 because file2 was not provided "

Does that mean my try and except block is not working because if
args.second  is None as in this case then it should print "The default
error is err-1 because file2 was not provided "

Please advice ,

Thanks,


> -- Forwarded message --
> From: Peter Otten <__pete...@web.de>
> To: tutor@python.org
> Cc:
> Bcc:
> Date: Sun, 27 Jan 2019 10:30:12 +0100
> Subject: Re: [Tutor] python - files
> Cameron Simpson wrote:
>
> > Mats has mentioned the modules getopt and argparse etc. These are
> > primarily aimed at option parsing ("-v", "-o foo"). Your situation
> > occurs _after_ the option parsing (in your case, there are no options).
>
> Not argparse. The main advantage over optparse is its handling of
> positional
> arguments. Your custom logic
>
> >   def main(argv):
> > cmd = argv.pop(0)   # collect the command word
> > badopts = False
> > # mandatory first argument
> > if not argv:
> >   print("%s: missing first argument" % cmd, file=sys.stderr)
> >   badopts = True
> > else:
> >   first = argv.pop(0)
> >   # optional second argument
> >   if argv:
> > second = argv.pop(0)# explicit argument 2, use it
> >   else:
> > second = None   # or some otherdefault
> >   if argv:
> > print("%s: extra arguments: %r" % (cmd, argv), file=sys.stderr)
> > badopts = true
> > if badopts:
> >   print("%s: invalid invocation, aborting" % cmd, file=sys.stderr)
> >   return 2
> > ... work with first and second ...
>
> can roughly be replicated with the two lines
>
> parser.add_argument("first")
> parser.add_argument("second", nargs="?")
>
> A working script:
>
> $ cat test.py
> #!/usr/bin/python3
> import argparse
>
> def main():
> parser = argparse.ArgumentParser()
>
> parser.add_argument("first")
> parser.add_argument("second", nargs="?")
>
> args = parser.parse_args()
>
> print("first:", args.first)
> print("second:", args.second)
>
> if __name__ == "__main__":
> main()
>
> $ ./test.py
> usage: test.py [-h] first [second]
> test.py: error: the following arguments are required: first
>
> $ ./test.py -h
> usage: test.py [-h] first [second]
>
> positional arguments:
>   first
>   second
>
> optional arguments:
>   -h, --help  show this help message and exit
>
> $ ./test.py ONE
> first: ONE
> second: None
>
> $ ./test.py ONE TWO
> first: ONE
> second: TWO
>
> $ ./test.py ONE TWO THREE
> usage: test.py [-h] first [second]
> test.py: error: unrecognized arguments: THREE
>
> Argparse makes a usable standard command line interface easy to set up (if
> you need non-standard behaviour it gets a bit harder).
>
> There is also a companion module argcomplete (not in the stdlib) that
> enables autocompletion.
>
>
>
>
>
>
> -- Forwarded message --
> From: Cameron Simpson 
> To: tutor@python.org
> Cc:
> Bcc:
> Date: Sun, 27 Jan 2019 20:54:13 +1100
> Subject: Re: [Tutor] python - files
> On 27Jan2019 10:30, Peter Otten <__pete...@web.de> wrote:
> >Cameron Simpson wrote:
> >> Mats has mentioned the modules getopt and argparse etc. These are
> >> primarily aimed at option parsing ("-v", "-o foo"). Your situation
> >> occurs _after_ the option parsing (in your case, there are no options).
> >
> >Not argparse. The main advantage over optparse is its handling of
> positional
> >arguments.
>
> I stand corrected.
>
> >Your custom logic
> [...]
> &g

Re: [Tutor] python - files

2019-01-27 Thread Cameron Simpson

On 27Jan2019 10:30, Peter Otten <__pete...@web.de> wrote:

Cameron Simpson wrote:

Mats has mentioned the modules getopt and argparse etc. These are
primarily aimed at option parsing ("-v", "-o foo"). Your situation
occurs _after_ the option parsing (in your case, there are no options).


Not argparse. The main advantage over optparse is its handling of positional
arguments.


I stand corrected.


Your custom logic

[...]

can roughly be replicated with the two lines

parser.add_argument("first")
parser.add_argument("second", nargs="?")
[... extended example ...]


Thank you!

Cheers,
Cameron Simpson 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] python - files

2019-01-27 Thread Peter Otten
Cameron Simpson wrote:

> Mats has mentioned the modules getopt and argparse etc. These are
> primarily aimed at option parsing ("-v", "-o foo"). Your situation
> occurs _after_ the option parsing (in your case, there are no options).

Not argparse. The main advantage over optparse is its handling of positional 
arguments. Your custom logic 

>   def main(argv):
> cmd = argv.pop(0)   # collect the command word
> badopts = False
> # mandatory first argument
> if not argv:
>   print("%s: missing first argument" % cmd, file=sys.stderr)
>   badopts = True
> else:
>   first = argv.pop(0)
>   # optional second argument
>   if argv:
> second = argv.pop(0)# explicit argument 2, use it
>   else:
> second = None   # or some otherdefault
>   if argv:
> print("%s: extra arguments: %r" % (cmd, argv), file=sys.stderr)
> badopts = true
> if badopts:
>   print("%s: invalid invocation, aborting" % cmd, file=sys.stderr)
>   return 2
> ... work with first and second ...

can roughly be replicated with the two lines

parser.add_argument("first")
parser.add_argument("second", nargs="?")

A working script:

$ cat test.py
#!/usr/bin/python3
import argparse

def main():
parser = argparse.ArgumentParser()

parser.add_argument("first")
parser.add_argument("second", nargs="?")

args = parser.parse_args()

print("first:", args.first)
print("second:", args.second)

if __name__ == "__main__":
main()

$ ./test.py
usage: test.py [-h] first [second]
test.py: error: the following arguments are required: first

$ ./test.py -h
usage: test.py [-h] first [second]

positional arguments:
  first
  second

optional arguments:
  -h, --help  show this help message and exit

$ ./test.py ONE
first: ONE
second: None

$ ./test.py ONE TWO
first: ONE
second: TWO

$ ./test.py ONE TWO THREE
usage: test.py [-h] first [second]
test.py: error: unrecognized arguments: THREE

Argparse makes a usable standard command line interface easy to set up (if 
you need non-standard behaviour it gets a bit harder).

There is also a companion module argcomplete (not in the stdlib) that 
enables autocompletion.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] python - files

2019-01-26 Thread Cameron Simpson
Mats has mentioned the modules getopt and argparse etc. These are 
primarily aimed at option parsing ("-v", "-o foo"). Your situation 
occurs _after_ the option parsing (in your case, there are no options).


Alan has talked about explicitly checking the length of sys.argv, much 
as you are doing, or accessing the (missing) argument and catching an 
exception.


There's a middle ground, which is a little more flexible, which is to 
_consume_ the command line arguments. The argv array is a list, and can 
be modified. So:


 def main(argv):
   cmd = argv.pop(0)   # collect the command word
   badopts = False
   # mandatory first argument
   if not argv:
 print("%s: missing first argument" % cmd, file=sys.stderr)
 badopts = True
   else:
 first = argv.pop(0)
 # optional second argument
 if argv:
   second = argv.pop(0)# explicit argument 2, use it
 else:
   second = None   # or some otherdefault
 if argv:
   print("%s: extra arguments: %r" % (cmd, argv), file=sys.stderr)
   badopts = true
   if badopts:
 print("%s: invalid invocation, aborting" % cmd, file=sys.stderr)
 return 2
   ... work with first and second ...

You can see here that we process the arguments from left to right, 
consuming the valid ones as we find them, and setting a flag for 
incorrect arguments. At the end we test the flag and abort if it is set.  
otherwise we process knowing we have valid values.


One important aspect of the above code is that you do not wire in an 
explicit length for sys.argv such as 2 or 3. That way you can easily 
change your code later if you want more arguments without running around 
adjusting such fixed numbers.


The other important aspect is usability: the above code complains about 
each issue it encounters, and finally quits with an additional message.  
In a real programme that addition message would include a "usage" 
message which describes the expected arguments.


Cheers,
Cameron Simpson 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] python - files

2019-01-26 Thread Mats Wichmann
On 1/26/19 1:20 AM, Asad wrote:
> Hi All ,
> 
>I would like to know how do I make and option file as an argument on
> command propmnt in python 

I don't know your context for asking this question. Alan has already
explained what you need to do for your issue, and whatever your needs it
is certainly worthwhile to understand how sys.argv works.


Just wanted to add, you find yourself having a need for processing a
non-trivial amount of arguments, this is a problem that is well
addressed in the Python community... the standard library now has three
modules for that - the "original" (UNIX/POSIX like) getopt module, the
currently preferred argparse module, and the optparse module it replaced
(which is now considered deprecated), as well as several very good
modules which are not in the standard library like docopt and click
(just naming two as examples, not endorsing anything).  So you don't
need to reinvent the wheel here if you have heavy duty needs - spend
your time on other parts of the problems you are solving.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] python - files

2019-01-26 Thread Alan Gauld via Tutor
On 26/01/2019 08:20, Asad wrote:

>At present I using :
> 
>   if len(sys.argv) == 3:
> first = sys.argv[1]
> second = sys.argv[2]
>   else:
> print "enter the second argument"

> It works well for the following command :
> python test.py file1 file2

Correct because it tests if there are 2 arguments passed

> However I have another case where only file1 may be present so file1 is
> mandatory for this script to run however file2 is optionnal :
> 
>   if len(sys.argv) == 2:
> first_log = sys.argv[1]
> second_log = sys.argv[2]

But this will always give an error because you test
for only one argument but then try to read two!
It will always give an error.

> It gives error :
> 
>second_log = sys.argv[2]
> IndexError: list index out of range
> 
> 
> How do I acheive this because if python test.py file1 file2   then I would
> process both files .

You need to check how many arguments are passed.

if len(sys.argv) == 2:
   # read one argument
elif len(sys.argv) == 3:
  # read 2 arguments
elif ... etc

You could alternatively use exception handling to
catch the IndexError but I think the explicit test
in this case more clearly shows what you are intending.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] python - files

2019-01-26 Thread Asad
Hi All ,

   I would like to know how do I make and option file as an argument on
command propmnt in python .

   At present I using :

  if len(sys.argv) == 3:
first = sys.argv[1]
second = sys.argv[2]
  else:

print "enter the second argument"
It works well for the following command :
python test.py file1 file2

However I have another case where only file1 may be present so file1 is
mandatory for this script to run however file2 is optionnal :


  if len(sys.argv) == 2:
first_log = sys.argv[1]
second_log = sys.argv[2]

pthon test.py file1

It gives error :

   second_log = sys.argv[2]
IndexError: list index out of range


How do I acheive this because if python test.py file1 file2   then I would
process both files .

If python test.py file1  is given then I would process file1 using the
variable first_log .


Please advice .

Thanks,
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor