Andrew Channels Dexter Pinion

Wherein I write some stuff that you may like to read. Or not, its up to you really.

November 04, 2003

Right Padding A String

I've been writing some Java today, shock horror. I approached it as if I was writing some Python code, but just with more symbols in the source code.

It was a nice reminder that even in such similar languages, common idioms don't necessarily travel. As an example I wanted to right pad a string. This isn't supported by the String class, so I wrote a method;

public String rightPad(String s, int length, char pad) {
	StringBuffer buffer = new StringBuffer(s);
	int curLen=s.length();
	if (curLen < length)
	{
		for (int i=0; i<length; i++)
		{
			buffer.append(pad);
		}
	}
	return buffer.toString();
}

Then I tried to implement it in Python. Here is my first pass;

def fill(fillString, toLength, fillChar):
    while len(fillString) < toLength:
        fillString += fillChar
    return fillString

Which is pretty much a direct copy of the Java code. But, I thought, there must be a more Pythonic way, so I came up with;

def newFill(fillString, toLength, fillChar):
    return fillString+''.join([fillChar for x in range(len(fillString),toLength)])

Hmmm, I'm not sure if its better, or just more obscure. It looks awfully LISP like to me.

Posted by Andy Todd at November 04, 2003 08:28 PM

Comments

fillLength = toLength - len(fillString)
return fillString + fillChar*fillLength

Posted by: simon on November 4, 2003 08:53 PM

Python 2.3.1 (#1, Sep 24 2003, 16:45:45)
[GCC 3.2.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from timeit import Timer
>>> def fillLength(s, l, c):
... return ''.join([s,] + [c,] * (l - len(s)))
...
>>> t = Timer(stmt="fillLength('pippo', 7, ' ')", setup="def fillLength(s, l, c):\n return ''.join([s,] + [c,] * (l - len(s)))") >>>
>>> t.timeit()
9.507375955581665
>>> t2 = Timer(stmt="newFill('pippo', 7, ' ')", setup="def newFill(fillString, toLength, fillChar):\n return fillString+''.join([fillChar for x in range(len(fillString),toLength)])")
>>> t2.timeit()
11.33608603477478
>>>

Posted by: ludo on November 5, 2003 12:10 AM

forgot the fastest

>>> t = Timer(stmt="fillString('pippo', 7, ' ')", setup="def fillString(s, l, c):\n return s + c * (l - len(s))")
3.0397789478302002
>>>

Posted by: ludoo on November 5, 2003 12:19 AM

And as for Java, don't reinvent the wheel:

http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/StringUtils.html#rightPad(java.lang.String,%20int,%20char)

Posted by: Simon Brunning on November 5, 2003 09:10 AM

Hmmm. Buggered *that* UR%L up, didn't I. Any road up, I'm sure you can find it - the Jakarta Commons Lang package.

Posted by: Simon Brunning on November 5, 2003 09:21 AM

Ah yes Simon, but that's Open Source and our Java visionaries here at work don't hold with any of that kind of rubbish

Posted by: Andy Todd on November 5, 2003 05:34 PM

Yeah - bunch of commie pinkos, the open source crowd. ;-)

Posted by: Simon Brunning on November 6, 2003 01:15 PM

You can shorten the Java one to this:

public String rightPad(String s, int length, char pad)
{
if (s.length() >= length) return s;
StringBuffer buffer = new StringBuffer(s);
for (int i = length - s.length(); i > 0; --i) buffer.append(pad);
return buffer.toString();
}

Posted by: Phillip Pearson on January 7, 2004 02:35 AM

It looks like your Java rightPad method doesn't actually work correctly. Why are you going from i = 0 to i = length?

Posted by: Titus Barik on May 17, 2005 07:28 AM