2

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.

Community
  • 1
  • 1
juggler
  • 319
  • 1
  • 5
  • 16
  • alternate solution I just thought of.. store the table with all it's numbers in one mega-variable, and insert it into the latex that way. – juggler Feb 27 '14 at 21:34
  • Given that the code doesn't do what you want; could you describe what you want to do in plain English (what is your input, what is the corresponding output)? – jfs Feb 27 '14 at 22:01
  • Are you expecting your users to input something like: `python foo.py --title xxx --2456 something --4912 else`? Where 'something' would replace a default value of '2456' in the final `content`? – hpaulj Feb 28 '14 at 02:30
  • Another way to put my last comment - what's the purpose of `argparse`? – hpaulj Feb 28 '14 at 04:08
  • Where do these strings come from? Are you generating them in the code, or reading them from some where else. The use of `argparse` only makes sense if you want to enter them via the commandline. – hpaulj Feb 28 '14 at 16:36
  • They are generated in a different part of the code. This code is in a definition in a class, and the strings are sent in as variables. the person who came up with the scheme has done something fancy to make something usually used in the context of the command-line work outside this context. See: http://stackoverflow.com/questions/8085520/generating-pdf-latex-with-python-script – juggler Feb 28 '14 at 16:52

2 Answers2

1

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.

Community
  • 1
  • 1
Peter Westlake
  • 4,894
  • 1
  • 26
  • 35
  • I got all excited there.. but I get this error message: `Traceback (most recent call last): File "SO_answer.py", line 12, in %(number)s''' % number TypeError: format requires a mapping` – juggler Feb 28 '14 at 16:43
  • Which can be simplified to: `for i in range(0,4): content += '\n %s' (2456*i)` – hpaulj Feb 28 '14 at 17:29
  • @hpaulj - something line that, yes: `for i in range(0,4): content += '\n %d' % (2456*i)` – Peter Westlake Feb 28 '14 at 17:32
  • ok, awesome! that works. I'll be accepting this, but could you possibly include a link to the documentation where this is explained (if there is such a place in it?), or explain here in more detail why it works? also the short-hand you've included? it would be nice to know.. (given I've already implemented my own solution (noted above), I probably won't be spending hours tracking this down, but might if you could help me figure out where to look.. – juggler Feb 28 '14 at 18:00
  • 1
    The correct link to the Python documentation would be https://docs.python.org/2/library/stdtypes.html#string-formatting – user1735594 Aug 02 '16 at 08:18
0

This is a wild guess but I think your ''' should be '\'' otherwise the second ' closes the first one and the third one hangs unpaired.

content = content + '\''
%(number_dict[i])s'\''
content = content + '\''
\end{document}'\''
tike
  • 2,234
  • 17
  • 19
  • In Python 3 quotes mark a multiline block of text. However sometimes it is clearer if you use `'one line \n 2nd line \n third'`. – hpaulj Feb 28 '14 at 03:11