sys.argv and while loop 
Author Message
 sys.argv and while loop

Using python 1.3 on an HP (UNIX) (to write my first Python script):

In the following script, the while loop doesn't exit as expected if one
of the variables in the conditional is assigned to equal sys.argv[1].
It works as expected if I explicitly set the variable to the number
(that is entered as the argument).

(stored in executable myscript.py)
#!/usr/local2/bin/python
import sys
count = 0
orbits = sys.argv[1]
while count < orbits:
    print count, orbits
    count = count + 1
    if count > 100:    # use this to prevent the infinite loop it gets
into
        sys.exit ( 1 )

The command line I use is:
myscript.py 16

The while loop does not exit when count becomes > 16 (until it hits the
"if" statement that I included to prevent the infinite loop).
If I replace the "orbits = sys.argv[1]" statement with "orbits = 16" and
run the script without the argument (but still importing sys), the while
loop does exit.

How can I define orbits to equal the value of the command line argument
and later use that variable to simply represent the number?

Julia Bell



Sun, 24 Oct 2004 22:34:23 GMT  
 sys.argv and while loop
Your problem stems from the fact that you are assuming that the variable
orbits is an integer, when in fact it is a string.
If you change your while clause to:

    while count < int(orbits)

or, after adding an "import string" to the top of your script (since I'm
not sure if the int function existed in Python 1.3):

    while count < string.atoi(orbits)

It should work fine.

Good luck.  =)

Quote:

> Using Python 1.3 on an HP (UNIX) (to write my first Python script):

> In the following script, the while loop doesn't exit as expected if one
> of the variables in the conditional is assigned to equal sys.argv[1].
> It works as expected if I explicitly set the variable to the number
> (that is entered as the argument).

> (stored in executable myscript.py)
> #!/usr/local2/bin/python
> import sys
> count = 0
> orbits = sys.argv[1]
> while count < orbits:
>     print count, orbits
>     count = count + 1
>     if count > 100:    # use this to prevent the infinite loop it gets
> into
>         sys.exit ( 1 )

> The command line I use is:
> myscript.py 16

> The while loop does not exit when count becomes > 16 (until it hits the
> "if" statement that I included to prevent the infinite loop).
> If I replace the "orbits = sys.argv[1]" statement with "orbits = 16" and
> run the script without the argument (but still importing sys), the while
> loop does exit.

> How can I define orbits to equal the value of the command line argument
> and later use that variable to simply represent the number?

> Julia Bell

--
Christopher Myers, Graduate Software Developer
Ingenta, Inc.
12 Bassett St.
Providence, RI  02903
ph:  401.331.2014 x 102

aim: chrismyers001


Sun, 24 Oct 2004 23:23:30 GMT  
 sys.argv and while loop


Quote:
> Using Python 1.3 on an HP (UNIX) (to write my first Python script):

If you can get that upgraded to something a bit more recent you will be
doing yourself a favour.

Quote:
> How can I define orbits to equal the value of the command line argument
> and later use that variable to simply represent the number?

The program arguments in sys.argv are all strings. You can compare a number
with a string, but you won't get the result you expect. What you have to do
is to convert the argument to an integer:

#!/usr/local2/bin/python
import sys
count = 0
orbits = int(sys.argv[1])
while count < orbits:
    print count, orbits
    count = count + 1
    if count > 100:    # use this to prevent the infinite loop
        sys.exit ( 1 )

A useful tip when weird things happen is to use the repr function when
printing the values:

Quote:
>>> count = 1
>>> orbits = '16'
>>> print count, orbits
1 16
>>> print repr(count), repr(orbits)
1 '16'

In this case the quotes would have shown that you were comparing a number
to a string.

--

int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?



Sun, 24 Oct 2004 23:27:11 GMT  
 sys.argv and while loop
Thanks for all of the advice.  I'm converting from perl, so I'm not used to
thinking about the difference between a string and a number in general.

(We are planning to upgrade our version of python in the next few months.)

Now that I know I have to worry about type, what is the best way to determine
if a string is convertible to a number (integer or float)?

If I use string.atoi(variable) or string.atof(variable), but variable cannot
be converted to an integer or float, I get an error.  I'm just learning about
catching exceptions, so I think I could figure out how to catch the error and
do something appropriate if that's the recommended approach.  But, is there a
better way (perform the test before trying to do the conversion)?

Julia Bell

Quote:



> > Using Python 1.3 on an HP (UNIX) (to write my first Python script):
> If you can get that upgraded to something a bit more recent you will be
> doing yourself a favour.

> > How can I define orbits to equal the value of the command line argument
> > and later use that variable to simply represent the number?

> The program arguments in sys.argv are all strings. You can compare a number
> with a string, but you won't get the result you expect. What you have to do
> is to convert the argument to an integer:

> #!/usr/local2/bin/python
> import sys
> count = 0
> orbits = int(sys.argv[1])
> while count < orbits:
>     print count, orbits
>     count = count + 1
>     if count > 100:    # use this to prevent the infinite loop
>         sys.exit ( 1 )

> A useful tip when weird things happen is to use the repr function when
> printing the values:

> >>> count = 1
> >>> orbits = '16'
> >>> print count, orbits
> 1 16
> >>> print repr(count), repr(orbits)
> 1 '16'

> In this case the quotes would have shown that you were comparing a number
> to a string.

> --

> int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
> "\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?



Mon, 25 Oct 2004 00:43:13 GMT  
 sys.argv and while loop

Quote:

> Using Python 1.3 on an HP (UNIX) (to write my first Python script):

> In the following script, the while loop doesn't exit as expected if one
> of the variables in the conditional is assigned to equal sys.argv[1].
> It works as expected if I explicitly set the variable to the number
> (that is entered as the argument).

> (stored in executable myscript.py)
> #!/usr/local2/bin/python
> import sys
> count = 0
> orbits = sys.argv[1]
> while count < orbits:
>     print count, orbits
>     count = count + 1
>     if count > 100:    # use this to prevent the infinite loop it gets
> into
>         sys.exit ( 1 )

> The command line I use is:
> myscript.py 16

Note that the arguments to the script get passed as strings, so
orbits = sys.argv[1] is actually equivalent to:
orbits = '16'

Python does not perform coercion of strings to numbers, but does define
an arbitrary order when comparing different types, hence "count < '16'" is
true for any number, so your loop never terminates.

What you really want is:

orbits = int(sys.argv[1])

Hope this helps,
Brian.



Mon, 25 Oct 2004 01:00:06 GMT  
 sys.argv and while loop

Quote:

> Thanks for all of the advice.  I'm converting from perl, so I'm not used to
> thinking about the difference between a string and a number in general.

> (We are planning to upgrade our version of python in the next few months.)

> Now that I know I have to worry about type, what is the best way to determine
> if a string is convertible to a number (integer or float)?

> If I use string.atoi(variable) or string.atof(variable), but variable cannot
> be converted to an integer or float, I get an error.  I'm just learning about
> catching exceptions, so I think I could figure out how to catch the error and
> do something appropriate if that's the recommended approach.  But, is there a
> better way (perform the test before trying to do the conversion)?

> Julia Bell

I recommend something like the following (obviously commenting and
uncommenting where appropriate to test):

str="3.14159"
#str="10000"
#str="foo"

try:
    num=string.atoi(str)
except ValueError:
    try:
        num=string.atof(str)
    except:
        num=str

if type(num) == type(1.0):
    print "Do float stuff in here"
elif type(num) == type(1):
    print "Do int stuff in here"
else:
    print "Value does not convert to a number"

I'd be very interested to see if there's a simpler way, though.

--
Christopher Myers, Graduate Software Developer
Ingenta, Inc.
12 Bassett St.
Providence, RI  02903
ph:  401.331.2014 x 102

aim: chrismyers001



Mon, 25 Oct 2004 01:12:54 GMT  
 sys.argv and while loop
Python 1.3....  Yiech!

Anyway, your script isn't working because the parameter you're passing
to it is coming in as a string and not an integer.  You said that when
you set orbits to 16 in the code it works.  That's because you're
setting it to an integer.  When you do  orbits = 16  it DOES work but
instead try  orbits = "16"  and you will notice the same bug.

So at some point in your code you will need to change orbits from a
string to an integer.  Like so...

import sys, string
count = 0
orbits = sys.argv[1]
orbits = string.atoi(orbits)
while count < orbits:
    print count, orbits
    count = count + 1
    if count > 100:    # use this to prevent the infinite loop it gets
        sys.exit ( 1 )

This should give you the result you're looking for...   I didn't just
do someone's homework, did I???

Emanuel Borges

Quote:

> Using Python 1.3 on an HP (UNIX) (to write my first Python script):

> In the following script, the while loop doesn't exit as expected if one
> of the variables in the conditional is assigned to equal sys.argv[1].
> It works as expected if I explicitly set the variable to the number
> (that is entered as the argument).

> (stored in executable myscript.py)
> #!/usr/local2/bin/python
> import sys
> count = 0
> orbits = sys.argv[1]
> while count < orbits:
>     print count, orbits
>     count = count + 1
>     if count > 100:    # use this to prevent the infinite loop it gets
> into
>         sys.exit ( 1 )

> The command line I use is:
> myscript.py 16

> The while loop does not exit when count becomes > 16 (until it hits the
> "if" statement that I included to prevent the infinite loop).
> If I replace the "orbits = sys.argv[1]" statement with "orbits = 16" and
> run the script without the argument (but still importing sys), the while
> loop does exit.

> How can I define orbits to equal the value of the command line argument
> and later use that variable to simply represent the number?

> Julia Bell



Mon, 25 Oct 2004 01:39:28 GMT  
 sys.argv and while loop


Quote:
> Thanks for all of the advice.  I'm converting from perl, so I'm not used to
> thinking about the difference between a string and a number in general.

A big difference between python and perl is the design choice between explicit
and implicit.

Many times perl will "do the right thing(tm)" for you and without telling you.
Sometimes you do not want this behaviour.  Python generally does what you tell
it to.

This requires a slightly different approach but you get used to it (and many of
us never liked the implicitness of perl which is what led us to python).



Mon, 25 Oct 2004 01:31:51 GMT  
 sys.argv and while loop

Quote:
> Many times perl will "do the right thing(tm)" for you and without
> telling you.  Sometimes you do not want this behaviour.  Python
> generally does what you tell it to.

'generally'.

As talked about in a recent thread about comparing strings and ints:

  Otherwise, objects of different types always compare unequal, and are
  ordered consistently but arbitrarily.

--
Frank Tobin             http://www.neverending.org/~ftobin/



Mon, 25 Oct 2004 04:40:00 GMT  
 sys.argv and while loop

Quote:

> Using Python 1.3 on an HP (UNIX) (to write my first Python script):

G'day, Julia. Welcome to Python. *Please* do yourself a favour and
grab a copy of Python 2.2 real soon now. Version 1.3 is not supported
for mission-critical extra-terrestrial use :-)

Quote:

> In the following script, the while loop doesn't exit as expected if one
> of the variables in the conditional is assigned to equal sys.argv[1].
> It works as expected if I explicitly set the variable to the number
> (that is entered as the argument).

> (stored in executable myscript.py)
> #!/usr/local2/bin/python
> import sys
> count = 0
> orbits = sys.argv[1]

You need orbits = int(sys.argv[1])
Python allows comparison between operands of differing types, so you
were comparing an int (count) with a string (orbits). 16 < "16" is
true, as is 17 < "16".

Quote:
> while count < orbits:

'while' works as advertised, but you will want to become familiar with
the for statement and the range() built-in function:

   for count in range(orbits):
      do_something()

Quote:
>     print count, orbits

In your original script (w/o the int() fix), replace this with:

   print repr(count), repr(orbits), count < orbits, count <
int(orbits)

This will make the int versus string problem plainer.

HTH,
John



Mon, 25 Oct 2004 04:56:42 GMT  
 sys.argv and while loop

Quote:
> >   Otherwise, objects of different types always compare unequal, and are
> >   ordered consistently but arbitrarily.

> "if September is greater than the moon: do_this()" makes no sense to me
> either. I do not fault the language for failures of programmers (-:

Weak argument.  If you're going to have a stronly typed language, then
comparing objects of differing types, or even similar ones without
something defined for their comparison, should be generally be a
TypeError.

Given your line of reasoning, why bother type-checking functions (e.g.,
making sure the correct signature is used?)?  We could just leave
uninitialized memory in the arguments' place and silently proceed on; it's
the programmer's fault for not giving the right number of arguments.

--
Frank Tobin             http://www.neverending.org/~ftobin/



Mon, 25 Oct 2004 05:05:10 GMT  
 sys.argv and while loop


Quote:

>> Many times perl will "do the right thing(tm)" for you and without
>> telling you.  Sometimes you do not want this behaviour.  Python
>> generally does what you tell it to.

> 'generally'.

> As talked about in a recent thread about comparing strings and ints:

>   Otherwise, objects of different types always compare unequal, and are
>   ordered consistently but arbitrarily.

"if September is greater than the moon: do_this()" makes no sense to me either.
 I do not fault the language for failures of programmers (-:


Mon, 25 Oct 2004 04:50:44 GMT  
 sys.argv and while loop

Quote:
> If I use string.atoi(variable) or string.atof(variable), but
> variable cannot be converted to an integer or float, I get an error.
> I'm just learning about catching exceptions, so I think I could
> figure out how to catch the error and do something appropriate if
> that's the recommended approach.  But, is there a better way
> (perform the test before trying to do the conversion)?

Probably not. The Pythonic way of seeing if something is going to work
is "try it and see" (and catch any exceptions). A Python guru (which I
am not) could explain why this is the recommended approach, but as I
understand it there are 2 reasons:

  - Exceptions are not expensive in Python.

  - If you are wondering whether some operation will work, it is very
  hard (especially in a dynamic language like Python) to anticipate
  all the conditions need to be satisfied. Trying the operation itself
  cuts to the heart of the matter.

One other comment: instead of string.atoi(value) you can use
int(value). It makes little difference in this case because the
elements of sys.argv are guaranteed to be strings, but in another
situation you want to allow the possibility that the value is
already an integer, or some other non-string type that can be
converted to an integer.

--
Mark Hadfield            "Ka puwaha et tai nei, Hoea tatou"

National Institute for Water and Atmospheric Research (NIWA)



Mon, 25 Oct 2004 05:14:51 GMT  
 sys.argv and while loop


Quote:

>> >   Otherwise, objects of different types always compare unequal, and are
>> >   ordered consistently but arbitrarily.

>> "if September is greater than the moon: do_this()" makes no sense to me
>> either. I do not fault the language for failures of programmers (-:

> Weak argument.  If you're going to have a stronly typed language, then
> comparing objects of differing types, or even similar ones without
> something defined for their comparison, should be generally be a
> TypeError.

I would be perfectly happy if "int < string" raised a TypeError.  But since it
doesn't I do not find the current behaviour worse than any other.

It could be worse "a"++ could actually mean something in python like it does in
perl (-:



Mon, 25 Oct 2004 05:18:05 GMT  
 sys.argv and while loop

Quote:

> try:
>     num=string.atoi(str)
> except ValueError:
>     try:
>         num=string.atof(str)
>     except:
>         num=str

> if type(num) == type(1.0):
>     print "Do float stuff in here"
> elif type(num) == type(1):
>     print "Do int stuff in here"
> else:
>     print "Value does not convert to a number"

> I'd be very interested to see if there's a simpler way, though.

Well, this would probably be as useful in most situations,
since the need to differentiate types that carefully is probably
rare:

try:
    num = float(str)
    print 'Do generic number stuff here'
except ValueError:
    print "Value not a number"

Obviously you know you could do that, since you were
able to come up with the more complex version above.
My point is merely that it is unlikely anything so
complex would often be necessary, so the "simpler way"
is perhaps just this little version.

-Peter



Mon, 25 Oct 2004 12:58:22 GMT  
 
 [ 19 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Chosing between sys.argv and sys.stdin

2. understanding sys.argv[]

3. sys module - argv, but no argc ??

4. sys.argv not found

5. catch empty sys.argv

6. sys.argv in Python 2.0 does not work?

7. ?sys.argv values more literally?

8. Win32 problems: Popen3 and sys.argv[0]

9. Sys.argv

10. sys.argv attribute error

11. Specifiying a module from sys.argv?

12. assignment to sys.argv[0]

 

 
Powered by phpBB® Forum Software