-2

While the 'if var:' statement works correctly in Python IDE, it is not behaving the same when run from a Python script. Any idea why is that?

Code to reproduce the problem:

%%writefile if_var.py
import argparse

def if_var_fn(Flag):
    if Flag:
        print(f'Flag is True: {Flag}')
    else:
        print(f'Flag is False or None: {Flag}')
        
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Process Flag argument.')
    parser.add_argument('Flag_', help='Enter Flag value')
    args = parser.parse_args()
    print(f'Value of args.Flag_: {args.Flag_}')
    print('Running if var ...')
    
    if_var_fn(args.Flag_)

The problem is that the passed argument always takes only one value: True

(base) /.../: python if_var.py 1
Value of args.Flag_: 1
Running if var ...
Flag is True: 1
(base) /.../: python if_var.py 0
Value of args.Flag_: 0
Running if var ...
Flag is True: 0
luk2302
  • 55,258
  • 23
  • 97
  • 137
crbl
  • 379
  • 2
  • 13
  • 4
    What do you think `bool('False')` is? – user2357112 Jul 03 '22 at 07:44
  • 2
    a non-empty string is considered Truthy, so True after passing into `bool()` – azro Jul 03 '22 at 07:48
  • 1
    Note for a boolean flag you'd conventionally use [`action='store_true'`](https://docs.python.org/3/library/argparse.html#action). – jonrsharpe Jul 03 '22 at 07:51
  • Yes bool('False') is True, but it does not solve the problem. Found a solution to cast the argument to integer. – crbl Jul 03 '22 at 07:55
  • Why don't you just use boolean values, rather than integers (i.e. `True` or `False`)? – ndc85430 Jul 03 '22 at 07:57
  • 1
    Command arguments are strings. If you want anything else, cast them using type= in `add_argument`, docs: https://docs.python.org/3/library/argparse.html#type . However, passing booleans as args is not clearly defined. Some programs use 1/0 or yes/no or true/false or all of them and usually case insensitive. Which option do you want to use in your program? – VPfB Jul 03 '22 at 08:06
  • A common convention for boolean flags which default to false is to enable them by specifying an option, and leave them disabled by not supplying that option. There are some marginal related conventions, like the now-abandoned GNU initiative to alse use `+` as an option character to ... uh, usually negate an existing option. – tripleee Jul 03 '22 at 08:09
  • @VPfB I stick with 1/0 therefore the argument can be declared as integer. – crbl Jul 03 '22 at 08:09
  • @FlorianC then your cast to int will work except that it will silently accept other integer values as well. – VPfB Jul 03 '22 at 08:12
  • See also https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse – VPfB Jul 03 '22 at 08:14
  • 1
    @VPfB It does exists 'choices' option for argument declaration. This will restrict the values to [0,1] – crbl Jul 03 '22 at 08:17
  • @FlorianC I agree with you that type+choices is a fine solution for accepting 0 as false and 1 as true. – VPfB Jul 03 '22 at 08:25

1 Answers1

0

One solution I found was to cast the argument to integer from argument type declaration and use choices to restrict the argument values to [0,1].

crbl
  • 379
  • 2
  • 13