[Tutor] interesting behaviour with postional output

Steven D'Aprano steve at pearwood.info
Tue Nov 15 00:32:56 CET 2011


Cranky Frankie wrote:
> I'm working on writing out postional output. When I use this statement:
> 
> print('%-40s%s' % (element_list[0], element_list[1]))	
> 
> I get nice, lined up columns on the screen. When I write to a file like this:
> 
> new_line = ('%-40s%s%s' % (element_list[0], element_list[1],'\n'))
> file_out.write(new_line)
> 
> a very funny thing happens. When I open the file in Notepad, the
> columns are not lined up, however when I switch the font to Courier,
> they * are* lined up. So what's happening is the output statement is
> working correctly - the second column starts in the 41st postion - but
> you have to use a non-proportional font to see it.

Well duh :)

No offense intended, but what you're describing isn't "a very funny 
thing". It's perfectly natural. You're lining text up in columns 
according to the *character position*, which naturally assumes that each 
character is the same width. If characters vary in width, you need to 
calculate *pixel widths* of each character, and align them according to 
the actual pixels used -- and that will depend on the precise details of 
which font face, size and style are being used, the font rendering 
algorithm used, and the resolution of the display device (printer or 
screen).

One alternative is to line up each column using tabs, written in Python 
as '\t', but that doesn't entirely solve the problem, because while it 
will eliminate small differences in pixel width, sufficiently large 
differences will throw your tabs out too. And you will be dependent on 
the viewer's tab settings: what they will see will vary according to the 
application's handling of tabs and where the user sets their tab stops.

A particularly stupid text editor may treat each tab as if it were a 
single space; a programmer's editor will cause the tab to align to the 
next multiple of 8 spaces, or 4, or possibly some other value as set by 
the user; another editor may treat each tab as *exactly* 8 spaces, 
regardless of where the tab falls; a word processor application will 
probably allow the user to set custom tab stops rather than assume each 
tab is 8 spaces; etc.

If you expect the user to use a proper programmer's editor like vi or 
emacs, you can embed display instructions at the end of the file to 
instruct the editor which tab stops to use, and whether to use a 
proportional or non-proportional font. But if the user uses Notepad, or 
Microsoft Word, you have no control over the display format.

One sensible approach is to simply pass the responsibility for setting 
the display settings to the user. "Use a monospaced font" is not 
particularly hard for experienced computer users to follow. "Use Courier 
New" is simple enough for even the average user.

Another is to use something is a CSV file, and instruct them to open the 
file in a spreadsheet program like Excel instead of a text editor.

Or if you're really keen, you can generate a presentation format like 
PDF. That's basically the only way to be completely independent of the 
user's settings.



-- 
Steven



More information about the Tutor mailing list