By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,175 Members | 1,689 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,175 IT Pros & Developers. It's quick & easy.

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

P: n/a
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.
Jul 18 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
John F Dutcher wrote in message
<2c**************************@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

Jul 18 '05 #2

P: n/a
John F Dutcher wrote:
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.


are you sure they're not there, or is the problem just that print
doesn't show them to you? try using "repr" or "len":
import string
print repr(string.ljust("field", 15)) 'field ' print len(string.ljust("field", 15)) 15

also note that ljust doesn't do anything if the input string is
longer than the field width:
print len(string.ljust("fieldfieldfieldfield", 15))

20

</F>


Jul 18 '05 #3

P: n/a
There seems to be a difference between using IDLE to test the code and using
the same code in my CGI script as follows: (I'm using Python 2.3.1)
In the IDLE command shell this works exactly as expected, that is
ending spaces are preserved when joined to the 'rec' string:

ten = 'xxxxxxxxxx'
recd = []
recd.append(string.ljust(ten,15))
recd.append(string.ljust(ten,15))
recd.append(string.ljust(ten,15))
rec = string.join(recd,'')
print rec -----------------> ending spaces preserved
************************************************** ***********

In my CGI script where I retrieve 'form' data nothing works..
The use of a string to receive the form field first, and
then appending to 'recd'...or appending to 'recd' directly, both fail
to preserve the spaces....(which are preserved very well in the
IDLE mode using a string literal to start with, rather than 'form' data).
recd = []
lname = string.ljust(form.getfirst("lname",' '),15)
fname = string.ljust(form.getfirst("fname",' '),15)

recd.append(lname)
recd.append(fname)

recstr = string.join(recd,'')
print recstr ------------------> no ending spaces

"Fredrik Lundh" <fr*****@pythonware.com> wrote in message news:<ma************************************@pytho n.org>...
John F Dutcher wrote:
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.


are you sure they're not there, or is the problem just that print
doesn't show them to you? try using "repr" or "len":
import string
print repr(string.ljust("field", 15)) 'field ' print len(string.ljust("field", 15)) 15

also note that ljust doesn't do anything if the input string is
longer than the field width:
print len(string.ljust("fieldfieldfieldfield", 15))

20

</F>

Jul 18 '05 #4

P: n/a
In the IDLE command shell this works exactly as expected, that is
ending spaces are preserved when joined to the 'rec' string:
(If I don't import and use 'string.ljust), and use just 'ljust' I get
a "Namerror'(Python 2.3.1)

ten = 'xxxxxxxxxx'
recd = []
recd.append(string.ljust(ten,15))
recd.append(string.ljust(ten,15))
recd.append(string.ljust(ten,15))
rec = string.join(recd,'')
print rec -----------------> ending spaces preserved
************************************************** ***********

In my CGI script where I retrieve 'form' data nothing works..
The use of a string to receive the form field first, and
then appending to 'recd'...or appending to 'recd' directly both fail
to preserve the spaces....(which are preserved very well in the
IDLE mode using a string literal to start with) rather than 'form'data.
recd = []
lname = string.ljust(form.getfirst("lname",' '),15)
fname = string.ljust(form.getfirst("fname",' '),15)

recd.append(lname)
recd.append(fname)

recstr = string.join(recd,'')
print recstr ------------------> no ending spaces for fields

"Francis Avila" <fr***********@yahoo.com> wrote in message news:<vr************@corp.supernews.com>...
John F Dutcher wrote in message
<2c**************************@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.

Jul 18 '05 #5

P: n/a
Last shot ... then I'll leave you alone...I tried your 'fixedwidth'
function.
Almost predictably....it worked perfectly in IDLE when coded as below:
It has no effect at all when employed in the CGI script however, (the
returned
values do not have trailing spaces) ??

IDLE code:
def fixedwidth(string, width=15):
if len(string) > width:
return string[:width]
else:
return string.ljust(width)
ten = 'xxxxxxxxxx'
recd = []
recd.append(fixedwidth(ten))
recd.append(fixedwidth(ten))
recd.append(fixedwidth(ten))
rec = string.join(recd,'')
print rec
#f.close()
sys.exit()

Same code placed in CGI.... BUT....the passed string came in from the
form...can't see why there should be any difference.

"Francis Avila" <fr***********@yahoo.com> wrote in message news:<vr************@corp.supernews.com>...
John F Dutcher wrote in message
<2c**************************@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.

Jul 18 '05 #6

P: n/a
John F Dutcher wrote:
Last shot ... then I'll leave you alone...I tried your 'fixedwidth'
function.
Almost predictably....it worked perfectly in IDLE when coded as below:
It has no effect at all when employed in the CGI script however, (the
returned
values do not have trailing spaces) ??


I am now pretty sure that fixedwidth() or str.ljust() are *not* the problem
with your cgi script. Step back and look for something *completely*
different, e. g.:
- Is it an old file that you are checking for the extra spaces?
- Do you think that print writes to a file (it can, if you do:
print >> destfile, "sometext")?

If you cannot track down the bug yourself, shorten the cgi script as much as
you can and post it on c.l.py. Try to describe the problem you perceive and
make as few implicit assumptions as possible, i. e. "This is my script's
output cut and pasted" rather than "It does not do what I want".

Peter
Jul 18 '05 #7

P: n/a

John F Dutcher wrote in message
<2c**************************@posting.google.com>. ..

I have nothing to add to help you with your problem (aside from what Peter
already said), but just a tip:

(If I don't import and use 'string.ljust), and use just 'ljust' I get
a "Namerror'(Python 2.3.1)

You probably learned Python out of an old book, back when Python didn't have
string methods. What I mean is, don't use the string module (it's slated
for depreciation), but just use ljust as a method of your string:
''.join(['a','b','c']) 'abc' 'a'.ljust(5) 'a ' '1234'.isdigit() True dir('')

['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',
'__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
'__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__',
'__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__',
'__str__', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith',
'expandtabs', 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',
'replace', 'rfind', 'rindex', 'rjust', 'rstrip', 'split', 'splitlines',
'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

I'm sure you recognise many of those methods? To learn more, try help('')
in an interactive session.

--
Francis Avila
Jul 18 '05 #8

P: n/a
Peter Otten wrote:
I am now pretty sure that fixedwidth() or str.ljust() are *not* the problem
with your cgi script. Step back and look for something *completely*
different, e. g.:


Or maybe your browser holding an old response in its cache. Try holding
the shift key down while you click refresh.

Just a thought.

Steve

Jul 18 '05 #9

P: n/a
In article <2c*************************@posting.google.com> ,
Jo**********@urmc.rochester.edu (John F Dutcher) wrote:
In my CGI script where I retrieve 'form' data nothing works..
The use of a string to receive the form field first, and
then appending to 'recd'...or appending to 'recd' directly, both fail
to preserve the spaces....(which are preserved very well in the
IDLE mode using a string literal to start with, rather than 'form' data).
recd = []
lname = string.ljust(form.getfirst("lname",' '),15)
fname = string.ljust(form.getfirst("fname",' '),15)

recd.append(lname)
recd.append(fname)

recstr = string.join(recd,'')
print recstr ------------------> no ending spaces

Are you viewing your CGI program's output with an HTML browser?

Regards. Mel.
Jul 18 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.