1980: C
printf("%10.2f", x);
1988: C++
cout << setw(10) << setprecision(2) << showpoint << x;
1996: Java
java.text.NumberFormat formatter = java.text.NumberFormat.getNumberInstance(); formatter.setMinimumFractionDigits(2); formatter.setMaximumFractionDigits(2); String s = formatter.format(x); for (int i = s.length(); i < 10; i++) System.out.print(' '); System.out.print(s);
2004: Java
System.out.printf("%10.2f", x);
2008: Scala and Groovy
printf("%10.2f", x)
(from http://www.horstmann.com)
To complete the circle I'd add:
2009: Go
fmt.Printf("%10.2f", x)
Take a simple example in the lines of "I've seen {0} {1} {2}".format("John", "eat", "an apple") ...and try localizing this message into e.g. German.
I have a feeling that printf-style is one of the reasons, why the texts in localized versions of some programs are as bad as they are.
I don't buy the internationalization argument however. You have to explicitly select strings for i18n anyway and run them through something that retrieves the data from a catalogue based on the current language. It's not like you will override str.__mod__ to start i18n.
And if you want to do it right, there are more complex rules that need a special formatting language. For example if you want to display {count} error/errors, then the text of error/errors will vary based on language not just based on count 0/1/more but even more wildly based on language. E.g. some have a special noun declension for 2. For example in Polish, that might be when there are 5 errors: http://blogs.transparent.com/polish/cardinal-numbers/
>>> "%(name)s has %(count)d %(thing)s" % {'thing': 'bananas', 'count': 10, 'name': "Phil"}
'Phil has 10 bananas' >>> "{name} has {count} {thing}".format(
thing='bananas', count=10, name='Phil')
'Phil has 10 bananas'
It also allows for more complex expressions inside of format specifiers, so if you need to grab data out of an object, you can do something like: >>> from collections import namedtuple
>>> Sentence = namedtuple('Sentence', ['name', 'thing', 'count'])
>>> s = Sentence(name='Phil', thing='bananas', count=10)
>>> '{dat[0]} has {dat.count} {dat.thing}'.format(dat=s)
'Phil has 10 bananas'
which is verbose and contrived here, but could be immensely useful in cases like >>> '... {numeral[5]} {item.plural}'.format(
numeral=fr_numerals, item=animal)
'... cinq animaux' templates = {'en': '{adj} {noun}', 'fr': '{noun} {adj}'}
print(templates['fr'].format(noun='fromage', adj='délicieux')
but that's still a hack, and doesn't even come close to addressing cases like Chinese's "{adj} {counter_word[noun]} {noun}" or gender concord or any of the myriad other things you come across in practice.Edit: used 'positional' instead of 'named'.
"{:10.2f}".format(x) printf "%10.2f" x
(Note the lack of parenthesis or commas)A few other PEP 3101 examples worth mentioning (and their printf equivalents):
'{1} {0} and {2} {0}'.format('Wiggin', 'Andrew', 'Valentine')
'%s, %s and %s' % tuple('%s Wiggin' % i for i in ('Andrew', 'Valentine'))
>>> 'Andrew Wiggin and Valentine Wiggin'
'{:<{w}} , {:<{w}} ,'.format('one', 'two', w=10)
'%s , %s ,' % ('one'.ljust(10), 'two'.ljust(10))
>>> 'one , two ,'
'{:^{w}} , {:^{w}} ,'.format('one', 'two', w=10)
'%s , %s ,' % ('one'.center(10), 'two'.center(10)
>>> ' one , two ,'
# see object.__format__() [4]
'today is: {:%a %b %d}'.format(datetime.now())
'today is: %s' % datetime.now().strftime('%a %b %d')
>>> 'today is: Tue May 08'
Imho, they really are quite flexible and allow for more elegant constructs when needed. Calling them 'vastly inferior' is unwarranted, especially since using them is not mandatory in any way.[1] http://www.python.org/dev/peps/pep-3101/
[2] http://docs.python.org/release/3.0.1/whatsnew/3.0.html#chang...
[3] http://docs.python.org/release/3.1.5/library/string.html#for...
[4] http://docs.python.org/release/3.1.5/reference/datamodel.htm...
Many core contributors have sided with printf-style and the community has spoken up a few times about wanting printf-style to stay around. I don't think we'll ever reach a majority siding with removal of it.
You're repeating yourself. Why? Because C can't know what types you are passing to it.
So you have to explicitly do '%d' or '%s' to let printf know what this is.
But yes, I think it's easier to type than {0}