3

I can't seem to figure out a straightforward way to make code that finds the number of items to format, asks the user for the arguments, and formats them into the original form.

A basic example of what I'm trying to do is as follows (user input starts after ">>> "):

>>> test.py
What is the form? >>> "{0} Zero {1} One"
What is the value for parameter 0? >>> "Hello"
What is the value for parameter 1? >>> "Goodbye"

The program would then use print(form.format()) to display the formatted inputs:

Hello Zero Goodbye One

However if the form had 3 arguments, it would ask for parameters 0, 1 and 2:

>>> test.py (same file)
What is the form? >>> "{0} Zero {1} One {2} Two"
What is the value for parameter 0? >>> "Hello"
What is the value for parameter 1? >>> "Goodbye"
What is the value for parameter 2? >>> "Hello_Again"
Hello Zero Goodbye One Hello_Again Two

This is the most basic application that I can think of that would use a variable amount of things to format. I have figured out how to make variables as I need them using vars() but as string.format() can't take in lists, tuples, or strings, I can't seem to make ".format()" adjust to the number of things there are to format.

pppery
  • 3,731
  • 22
  • 33
  • 46
Razz Abuiss
  • 53
  • 1
  • 4

4 Answers4

6
fmt=raw_input("what is the form? >>>")
nargs=fmt.count('{') #Very simple counting to figure out how many parameters to ask about
args=[]
for i in xrange(nargs):
    args.append(raw_input("What is the value for parameter {0} >>>".format(i)))

fmt.format(*args)
          #^ unpacking operator (sometimes called star operator or splat operator)
mgilson
  • 300,191
  • 65
  • 633
  • 696
  • Not only did you give a great solution, but using format on the input makes the program way simpler than the way I had it. Thanks! – Razz Abuiss Jul 10 '12 at 21:54
2

The easiest way is to simply try to format using whatever data you have, and if you get an IndexError you don't have enough items yet, so ask for another one. Keep the items in a list and unpack it using the * notation when calling the format() method.

format = raw_input("What is the format? >>> ")
prompt = "What is the value for parameter {0}? >>> "
parms  = []
result = ""
if format:
    while not result:
        try:
            result = format.format(*parms)
        except IndexError:
             parms.append(raw_input(prompt.format(len(parms))))
print result
kindall
  • 178,883
  • 35
  • 278
  • 309
  • Just to be complete, you should probably check that `format` isn't `''` – mgilson Jul 10 '12 at 21:54
  • Yeah, that's where I would put it too. Good answer now. I like it slightly better than mine (+1) -- *edit* why did you move it? `while format and not result` seems cleaner to me. Performance isn't an issue here since you're waiting for user input anyway... – mgilson Jul 10 '12 at 21:57
  • 1
    Yeah, I just thought it was clearer as a separate statement. Tomato, tomato. – kindall Jul 10 '12 at 21:58
  • 1
    Funny, when I read that, `Tomato` and `tomato` sound the same in my head ;). – mgilson Jul 10 '12 at 22:00
  • you don't need to check `if format` if you use `while True:` instead of `while not result` (add `break` if there is no exception) – jfs Jul 10 '12 at 22:17
  • it won't work if `format="{0}"` and user inputs empty string (the result should be empty in this case). See the fix in [my answer](http://stackoverflow.com/a/11435979/4279) – jfs Jul 11 '12 at 15:24
2

Here's a modified kindall's answer that allows empty result for non-empty format string:

format = raw_input("What is the format? >>> ")
prompt = "What is the value for parameter {0}? >>> "
params  = []

while True:
    try:
        result = format.format(*params)
    except IndexError:
        params.append(raw_input(prompt.format(len(params))))
    else:
        break
print result
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Yeah, this is probably the best solution. I hate manually breaking out of loops if it can be avoided (far more elegant to write a proper condition) but it doesn't seem possible in this case. – kindall Jul 11 '12 at 16:16
1

You just need to use * in front of the last parameter name and all subsequent ones will be grouped into that one. You can then iterate over that list as you desire.

How to make variable argument lists in Python

Community
  • 1
  • 1
chrisjleaf
  • 23
  • 4