juggler juggler - 4 months ago 12
Python Question

how to parse multiple strings into a string variable using a loop python

Following my earlier question: ValueError: unsupported format character ', I have another. hopefully worth of SO.

Here is a code that should give you a flavour of what I want to do:

import argparse
title = 'Title'
content='\centerline{\Large %(title)s}'

parser=argparse.ArgumentParser()

parser.add_argument('--title', default=title)

for i in range(0,4):
number = str(2456*i)
content = content + '''
%(number)s'''

parser.add_argument('--number', default=number)

content = content + '''
\end{document}'''



args=parser.parse_args()
content%args.__dict__
print content%args.__dict__
print ' '

print args.__dict__


It gives the following output:

\centerline{\Large Title}
7368
7368
7368
7368
\end{document}

{'number': '7368', 'title': 'Title'}


It works, but the numbers are all the same. What I'd like to do ultimately is take numbers produced elsewhere and place them in the variable. Automatically produce a latex table with python.

Here is latest attempt to do this. it's pretty ugly..

import argparse
title = 'Title'
content='\centerline{\Large %(title)s}'
number_dict = dict()
for i in range(0,4):
number_dict[i] = str(2456*i)
content = content + '''

%(number_dict[i])s'''
content = content + '''

\end{document}'''

parser=argparse.ArgumentParser()

parser.add_argument('--title', default=title)
parser.add_argument('--' + number_dict[i], default=number_dict[i])

args=parser.parse_args()
content%args.__dict__
print content%args.__dict__
print ' '

print args.__dict__


any thoughts?

Edit:

1) I believe I have solved this problem for the moment, see the first comment. the question remains interesting though.

2) This code is not meant to be used from the command-line.

3) I want to use it to input the entries of a table. There might be many entries, so I don't want to hard-code each line of data for inclusion in the latex document the way it is done in ValueError: unsupported format character ' and referenced questions.

Put it this way: in the working code above, the syntax:

%(number)s


along with:

parser.add_argument('--number', default=number)


is used to place the string 'number' into the latex code. I would like to implement this in a loop so that I can first place string1 into the latex code, then string2, then string3, and so on, as many as I have. might be 20 different strings, might be 35, might be 4. Can all these different strings be placed in the latex code (say in each of the cells of a table) with only one instance of something equivalent to the code segment: %(number)s, and one instance of something equivalent to the code segment: parser.add_argument('--number', default=number) inside a loop?

you can see my attempt to do this by re-defining "number" as a dictionary, and telling python which entry of the dictionary to insert.

I hope that's clearer.

Answer

The problem is that you are building up the format string in the loop, which gives something with the same variable several times:

'''
 %(number)s
 %(number)s
'''

After the loop, the variable number has the last value, because a Python variable can only have one value at a time! The fix is to do the formatting in the loop when you have each value available:

for i in range(0,4):
  number = str(2456*i)
  content = content + '''
  %(number)s''' % {'number': number}

Edited to add details requested by the OP:

There's a section in the Python docs on string formatting. It explains both the dictionary form of formatting using named items, and the simpler form which looks like this:

for i in range(0,4):
    content += '\n %d' % (2456*i)

In the first case, the format string is expanded by looking in the dict for the name given inside the %(....)s. In the second case, there's just one value and one format item, so Python has no problem knowing which value to substitute in. If the format string has more than one %, the second argument should be a tuple, and the elements of the tuple are used to expand each % in turn. Finally, %d (for "digits") turns a number into a string, so you don't need to call str() yourself.

The reason your original code was printing the same number every time was that you only plugged in the number at the end instead of substituting the successive values calculated each time round the loop.