Using 'string.ljust' to try and hold a fixed width.......

Francis Avila francisgavila at yahoo.com
Wed Nov 19 09:57:19 EST 2003


John F Dutcher wrote in message
<2c82369d.0311190538.3789f2a1 at posting.google.com>...
>I use code like the following to retrieve fields from a form:
>
>recd = []
>recd.append(string.ljust(form.getfirst("lname",' '),15))
>recd.append(string.ljust(form.getfirst("fname",' '),15))
>etc., etc.
>
>The intent is to finish by assigning the list to a string that I would
>write to disk: recstr = string.join(recd,'')
>
>The spaces expected are 'NOT' being provided with 'string.ljust'....
>
>If I simply print the field immediately as in:
>       print string.ljust(form.getfirst("lname",' '),15)
>
>they are not present; they are not present when assigned to the list,
>and, of course, they are not present in the final string.
>Is there a way to do this....so I can have spaces 'held' in the
>object I want to write to the file ??
>Thanks.

What does form.getfirst do?  (Also, unless you're using an ancient Python,
the strings objects themselves have ljust methods and you don't need the
string module.)

string.ljust will never truncate or modify a string, only extend it, so I
don't know what you mean by having spaces "held".  If the length of the
string is shorter than 15, string.ljust will return another string of length
15 with spaces on the right.  But if its longer, string.ljust will return
the string unchanged (i.e., still longer than 15 chars).

Since you're writing this stuff to disk, I presume you need fixed-width
strings, so you can reliably read things back?  If so, you can't safely use
string.ljust to pad *unless* you know *with certainty* that all strings fed
to it are 15 chars or shorter (because string.ljust won't truncate).  So why
not use struct.pack and struct.unpack instead of string.join?  (At least,
use string.joinwords() if you won't use ''.join())

E.g.:
recd = []
recd.append(form.getfirst("lname",' ')) # 'Avila' ?
recd.append(form.getfirst("fname",' ')) # 'Francis' ?

struct.pack('15s15s', *recd) # 'Avila\x00\x00Francis'
struct.unpack('15s15s', 'Avila\x00\x00Francis') # -> ('Avila', 'Francis')

Of course, struct pads with nulls, not spaces, so you already enter upon the
nasty world of binary files.  You could postprocess the struct.pack string
with ''.replace('\x00', ' '), but you'll have to strip trailing spaces when
you struct.unpack().

You could write your own fixed-width-string class/function:

def fixedwidth(string, width=15):
    if len(string) > width:
        return string[:width]
    else:
        return string.ljust(width)

There's a lot of repetition going on here, so you might want to think of
wrapping all this functionality up in a 'formFieldSerializer' class of some
sort.

If it's possible to change the structure of what you write to disk, there
are a number of much better alternatives.  Depending upon how rich your data
structure is and whether you need to name your fields, you could use (in
ascending complexity) colon-separated fields (':'.join(L). Remember to
escape colons in L!), the csv module, the ConfigParser module, or XML of
some kind (only if absolutely necessary).  There are many other modules in
the std library which do serialization of some kind, like MimeWriter, etc.,
which may be appropriate for what you're doing.  You can even use the db
modules if you need simple database.
--
Francis Avila









More information about the Python-list mailing list