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.

6
  • 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. Commented Feb 27, 2014 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)? Commented Feb 27, 2014 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? Commented Feb 28, 2014 at 2:30
  • Another way to put my last comment - what's the purpose of argparse? Commented Feb 28, 2014 at 4: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. Commented Feb 28, 2014 at 16:36

2 Answers 2

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.

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

5 Comments

I got all excited there.. but I get this error message: Traceback (most recent call last): File "SO_answer.py", line 12, in <module> %(number)s''' % number TypeError: format requires a mapping
Which can be simplified to: for i in range(0,4): content += '\n %s' (2456*i)
@hpaulj - something line that, yes: for i in range(0,4): content += '\n %d' % (2456*i)
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..
The correct link to the Python documentation would be docs.python.org/2/library/stdtypes.html#string-formatting
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}'\''

1 Comment

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'.

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.