1

I have

fruits = [apple, banana, pineapple, oranges]
sizes = [small, medium, large]

My code generates files for fruitproperty for each of the fruit-size combination. I am trying to do this two ways: (1) Code will compile for all fruit-size combinations (2) Code will compile for only specified fruit and it's three combinations.

I require maindir as compulsory argument while fruit name is optional argument

Following is my code:

parser = argparse.ArgumentParser(description = " require maindir path and if required fruit name for single compilation")
parser.add_argument('maindir', help = 'Give maindir path', action = 'store')
parser.add_argument("-p","--fruit",help = "Please give fruit name", type=str, default = "apple, banana, pineapple, oranges")
args = parser.parse_args()
print args
fruit =[str(item) for item in args.fruit.split(',')]
sys.argv[1]= os.environ.get(sys.argv[1],sys.argv[1])

def compile()
# Code for creating files for fruitproperty for the given fruit-size combination. 

Then I call the function as below:

if sys.argv[3] == fruit: 
   for size in sizes
       compile()
else: 
   for fruit in fruits
       for size in sizes
           compile() 

so even if I give optional argument, my code is by default compiling for all fruit-size combinations instead of the given specific fruit-size combinations. Where am I getting it wrong?

2
  • 1
    help = "Please give fruit name' - quotes are misbalanced, is this present in your original code? Commented Jul 11, 2015 at 17:17
  • yes it is. print args gives namespace(maindir = maindir, fruit = apple) but code compiles for all fruits. Commented Jul 11, 2015 at 17:19

2 Answers 2

1

Several problems:

In your first bit of code, you have a list fruit, which contains the list of fruit passed via a command-line argument. If it isn't specified, you have a default of "apple, pineapple, banana, orange".

Keep in mind: fruit is a list.

Now, here:

if sys.argv[3] == fruit: 

You're comparing one of the raw arguments (a string) with a list. First of all, why are you accessing sys.argv directly if you're using argparse? Second, why are you comparing a string to a list?

Also, this line:

for fruit in fruits

This "fruit" is shadowing (if different scope) or overwriting the old fruit variable. In this case you presume that the user hasn't supplied this parameter so doing so doesn't matter, but keep in mind that that's confusing—you should really be using more descriptive variables!

fruit =[str(item) for item in args.fruit.split(',')]

Note that the default is "apple, pineapple, banana, orange" - it has spaces. So here fruit = ["apple", " pineapple", " banana", " orange"] - those spaces are in there and will break string comparisons (if you were going to do any string comparisons). Suggest fixing this line to:

fruit = [str(item).strip() for item in args.fruit.split(',')]

strip() on a string will get rid of leading and trailing whitespace.

For the last bit of code, I suggest:

fruits_names = [str(item) for item in fruits]
for arg_fruit in fruit: # for each fruit passed as an argument
    if arg_fruit in fruits_names: # check if it's a valid fruit first
        for size in sizes: # if it's valid, "compile" for all sizes
            compile()

Note that I took out the if statement entirely, because you have a default value for args.fruit that lists all the fruit, so there's no situation in which you'd not have an args.fruit value to iterate over. If you wanted to rely on "no fruits argument = use the full list", set the fruit argument's default to None and check for if args.fruit is None instead.

Also, your variables are poorly named and make the above code confusing (someone reading the above might ask: "wait, what's the difference between the fruit and fruits variable?"). Let me suggest renames:

  • fruits → valid_fruits
  • sizes → valid_sizes
  • fruit → arg_fruit_list

That way, it's clear that some of those lists are the valid values, and the other list is the one passed via command line.

Sign up to request clarification or add additional context in comments.

11 Comments

Thanks. I tried your code. but it doesn't work, now it doesn't even compile.
Did you fix the spaces problem by calling strip in your list comprehension, as I mentioned? That seems like the first obvious gotcha. Print the two fruit lists (fruits and fruit per the original names) and check that the strings in the lists match up - if they don't the if arg_fruit in fruits line will fail every time. Also, if you renamed any variables, make sure you didn't make any mistakes there!
Yes, I am using strip() and print gives following outputs: print args: Namespace(maindir = 'maindir', fruit='apple'), print fruit gives ['apple'], print fruits = ['apple','banana','pineapple','oranges']. I didn't change any variables and kept as it is.
Everything looks fine there. Can you step through the loop, or just add print statements at every block, and check whether it's entering where it's supposed to? You'd expect arg_fruit == 'apple' in the one-and-only iteration of the for loop, and for the program to enter the if statement, and then for it to iterate over all three size values in the inner for loop. If all of that is correct, check your compile() function is correct after the changes (why does it not have arguments, anyway?).
Thanks a lot. so when I print arg_fruit, when it is supposed to print apple , is it giving weird output as o r a n g e (all in vertical manner) . What could be the problem?
|
1

Variable 'fruit' is a list, but you compare it with a string:

fruit =[str(item) for item in args.fruit.split(',')]
if sys.argv[3] == fruit: # this will always be False

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.