Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

docpicture

13 views
Skip to first unread message

bearoph...@lycos.com

unread,
Oct 13, 2008, 11:34:03 AM10/13/08
to
In Python code that processes some geometrical data I want to explain
what each variable like w1, w2, h2, h3, etc, means in the geometrical
objects. In such situation I don't use longer and more clear variable
names because in geometry I'm used to use short vertex/line/length
names, finding them more readable in the various formulas. Complex
formulas full of long names become huge and not much readable anyway.

To explain what those w1, w2, h2, h3 mean I can use text, or sometimes
ASCII art. But ASCII art is very low-resolution, so I have found that
a single little image can explain the meaning of lot of variables (and
other details) in a short space. Leaving the explanations to normal
textual comments.

So in this situation I have sometimes created a quite small image (1
bit/pixel) that encoded in png image format may require just few
hundred bytes. With Python I encode is binary data string in base64,
and I paste that as a string into the Python souce code. It probably
takes only 4-7 lines or so. With one or two more lines of Python I can
decode that string it and save as png again (usually this image
decoding line is commented out or executed only if a debugging global
variable is true). So far I have never used SVG vector images for such
purpose, but they are another possibility (the SVG ones may need to be
bzipped2 before the base64 encoding).

This way there's no risk of losing the essential image, because it's
embedded into the Python code.

Have you ever done this? Do you think such "documentation
picture" (analogous to a docstring) is an acceptable practice? I don't
need to do that often enough, so I think it doesn't deserve to become
supported by Python itself. While I presume emacs and similar
"advanced" editors can be programmed to recognize such string pictures
and show them inlined... :-)

Bye,
bearophile

Steven D'Aprano

unread,
Oct 13, 2008, 12:46:51 PM10/13/08
to
On Mon, 13 Oct 2008 08:34:03 -0700, bearophileHUGS wrote:

> So in this situation I have sometimes created a quite small image (1
> bit/pixel) that encoded in png image format may require just few hundred
> bytes. With Python I encode is binary data string in base64, and I paste
> that as a string into the Python souce code. It probably takes only 4-7
> lines or so.

[...]


> Have you ever done this? Do you think such "documentation picture"
> (analogous to a docstring) is an acceptable practice?

I've never done it, but I've often wished to be able to store diagrams in
my code.


> I don't need to do
> that often enough, so I think it doesn't deserve to become supported by
> Python itself.

I can't imagine Python having direct syntactic support for it, but I
don't see any reason why the standard library couldn't some day grow a
"docpicture" module, complete with a tiny (?) Tkinter app to display the
diagram when requested.

I think this would be useful. If you choose to share your code under an
appropriate licence, I would like to experiment with it.


--
Steven

sk...@pobox.com

unread,
Oct 13, 2008, 1:43:13 PM10/13/08
to Steven D'Aprano, pytho...@python.org

Steven> I can't imagine Python having direct syntactic support for it,
Steven> but I don't see any reason why the standard library couldn't
Steven> some day grow a "docpicture" module, complete with a tiny (?)
Steven> Tkinter app to display the diagram when requested.

Heck, if you go to the point of including a docpicture module, might as well
just support the feature in IDLE... Other IDEs would probably pick up the
feature as well.

Skip

sk...@pobox.com

unread,
Oct 13, 2008, 2:51:47 PM10/13/08
to Benjamin Kaplan, pytho...@python.org

Benjamin> So, the IDEs will support it. what happens when you run the
Benjamin> interpreter from the command line?

Probably get ignored. What else would you propose? It's not executable
code anyway, just a special comment or portion of a docstring.

S

Joe Strout

unread,
Oct 13, 2008, 4:55:00 PM10/13/08
to Python List
On Oct 13, 2008, at 2:43 PM, Benjamin Kaplan wrote:

> I mean what happens when you type help() into the interactive
> console on the command line? You will see the docstrings, and there
> will be a whole bunch of random hex characters there.


Good point. It might be better put in a specially-tagged comment,
rather than in the docstring.

I still think it's a nifty idea though.

Best,
- Joe

sk...@pobox.com

unread,
Oct 13, 2008, 5:41:58 PM10/13/08
to Benjamin Kaplan, Python List
>> Nothing. It's just a doc string containing a bunch of hex codes. Doc
>> strings are ignored by the interpreter (AIUI).

Benjamin> I mean what happens when you type help() into the interactive
Benjamin> console on the command line? You will see the docstrings, and
Benjamin> there will be a whole bunch of random hex characters there.

If an IDE can be trained to recognize and display such a picture I sorta
assume help() can be trained to recognize and ignore it.

Skip

Steven D'Aprano

unread,
Oct 13, 2008, 6:20:02 PM10/13/08
to

And if not, it's no big deal. Your help string has a clearly labeled few
lines of hex:

Help on function spam:

spam(...)
spam spam spam spam spam spam
spam spam spam spam with a fried egg on top

=== begin docpicture ===
1234567890ABCDEF
1234567890ABCDEF
1234567890ABCDEF
1234567890ABCDEF
=== end docpicture ===


Or similar. I'm sure people will cope, especially since it should be
relatively rare.

--
Steven

Scott David Daniels

unread,
Oct 14, 2008, 9:12:59 AM10/14/08
to
Steven D'Aprano wrote:
> And if not, it's no big deal. Your help string has a clearly labeled few
> lines of hex:
>
> Help on function spam:
>
> spam(...)
> spam spam spam spam spam spam
> spam spam spam spam with a fried egg on top
>
> === begin docpicture ===
> 1234567890ABCDEF...

> === end docpicture ===
> Or similar. I'm sure people will cope, especially since it should be
> relatively rare.
>
or you could even use:
'''<docpicture name="fig1.png" code="base64" version="1">
1234567890ABCDEF...
</docpicture>'''
A comment _not_ a docstring (only found by scanning the source).
which is easy enough to hunt for.

--Scott David Daniels
Scott....@Acm.Org

Steven D'Aprano

unread,
Oct 14, 2008, 9:58:10 AM10/14/08
to

+1 for docpictures

-1 for them being comments instead of docstrings. The whole point of
having them is to allow Python tools to operate on them. I should be able
to do this:


>>> import docpicture
>>> docpicture.gui(myfunction)


and get a nice Tk window showing the picture. There's all sorts of
functionality that you lose by making them comments and therefore
unavailable to Python tools. (Okay, technically this hypothetical
docpicture module could scan the source file -- assuming the source code
is even available, which isn't always true.)

But anyway, we're getting well ahead of ourselves here. Unless bearophile
is willing to share his code, or somebody reverse engineers it, this is
nothing more than vapourware.


--
Steven

bearoph...@lycos.com

unread,
Oct 14, 2008, 11:43:22 AM10/14/08
to
Steven D'Aprano:

> Unless bearophile is willing to share his code,

There's no code: all I do is written in my post, and so far I have
done it "manually" :-)

Bye,
bearophile

André

unread,
Oct 14, 2008, 12:23:31 PM10/14/08
to
On Oct 14, 10:58 am, Steven D'Aprano <st...@REMOVE-THIS-

Ok, the following is my first attempt at implementing this idea.
Of course, it could be improved by using reStructuredText in
the docstring and docutils to format it...

'''Experimental function allowing to view docstrings with embedded
images. The images are encoded in base 64.

(c) Andre Roberge
License: Adapt as you please, but preferably give credit to original
author (and any subsequent contributor).
'''

import base64
import os
import re
import sys
import webbrowser

html_template = "<html><head></head><body>%s</body>"
def docpicture_view(function):
"""
This is a test.

docpicture = reeborg_img.png

Some more explanation.
"""
source_module = sys.modules[function.__module__]

# extract image information from docstring, retrieve encoded data,
# decode, and write to file

image_name_pattern = re.compile("\s*docpicture\s*=\s*(.+?)\s")
image_filename =
image_name_pattern.search(function.__doc__).groups()[0]
base_name, ext = image_filename.split('.')
image = base64.b64decode(getattr(source_module, base_name))

image_file = open(image_filename, "wb")
image_file.write(image)
image_file.close()

# replace image information in docstring by link to image file,
# insert in an html template, create a new file that will be
displayed
# in a browser.

docpicture_pattern = re.compile("\s*(docpicture\s*=\s*.+?)\s")
text = docpicture_pattern.sub("<br><img src=%s><br>" %
image_filename,
function.__doc__)

html_file = open("test.html", 'w')
html_file.write(html_template % text)
html_file.close()

url = os.path.join(os.getcwd(), "test.html")
webbrowser.open(url)

reeborg_img = """\
iVBORw0KGgoAAAANSUhEUgAAABYAAAAeCAMAAAAfOR5kAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAD
AFBMVEUAAAAzMzNbW1v/AACAgICkpKTAwMD///
8AAAAS8uhyd1MAAAABD3UAADYAAAAAAFAAABkA
AAGFBJ4AAAkAADYAAAAAAFAAABkAAAAAAAAAABQAABcAAAkAAAQAAAQAAAQAAATxogDxoeQBD3UA
ADkAAAMAABMAABMBDusAAAAAACYFDpQAAAAAACaqAAD///
8V5iAV5hgS9XC1WqAS85wBDwG2L+RF
NyAAABMAABMBDutPyjgS9CC1WqC1VShP0RYAAABPyji1WqAS9CC1RBxP7jMAAAIBD3UAADkAAAMA
ABMAABMV5iAS9BhBx0G1DExCx4VCx43LD8i1DGxFM5sS9BhFM7JFM7oS9LRFM8QS9BgS9JjLD8jL
D8i1WqAS9DBCWLYABAEAAAC6Z1AAAAES9FzUhzRTBRAABAEAAAC6Z1DLD8i6q80AAAAS9JgS9HTU
tqPUhPzUhaQDBRoAAAEWIagWIcgABAAWX8gAAADUtik94ZFTBRAS9SwAAAAWX8g94ZwAAAAAAAAA
BAAAABMS9RAS9TjXBGfUiDD////UiCrUuJsAAADLD8hTBRAABAEAAAC6Z1B
+cqwAAAEAAAAAAAAA
AAAAAACKACEABADV8+N+cph
+8XAAAAAAAAQAAaYAAAIABAAAABMWIcgBCJ4AAAAAAAAAAAAAAAAA
AAAAAAAAAAAS8HSAFjwAAAUAAAVI2FSAGByAGKxI2GAAb1oS9fw97BsWX8gAAAAWIUgAAAQAAAAS
9mQ95ZgAAADXIloAAAAS9bzUtqPUhPzUhaQDBRoAAAEAAAAWX8gWIUgDBQES9dDUwr8S9gA90ZMD
BRo95ZgWX8jUiKYAAAAAAAIAAMgAABMWIVAS9ijUhzRTBRAAAA8AAAAAAAA95Zi6q80AAAAS9mQ9
5ZgS9pDUi9n90AAS9pDUiFoS9lDUiCoAAA895ZgS
+WgAABQAAAEAAAAAAAAAABAAAAAAAFAAAAEA
AAAAAAAS9kTxbGQS+TjXBGfUiDD////UiCoAAAAAAADKTwNHAAAACHRSTlP/////////
AN6DvVkA
AAB6SURBVHjardCLCsAgCAXQO7P8/z
+eyVxWEgzmKNghfEEES5CoqV5E7FFbIzKOao5SjJknj0yo
Gbt2fnKfOCQJHEt+43Lkdcp8J8bbBmEb7Jemh35cq/07axJjzhjIuJ+dsb/
2iZaSc3fO3qO88T+P
mpF5TB+YMp4bvwEGcAqR53QgIgAAAABJRU5ErkJggg==

"""

if __name__ == '__main__':
docpicture_view(docpicture_view)

bearoph...@lycos.com

unread,
Oct 14, 2008, 12:56:29 PM10/14/08
to
André:

> Ok, the following is my first attempt at implementing this idea.

I suggest you to change the program you use to encode your images,
because it's 1000 bytes, while with my program the same 256 colors
image needs just 278 bytes:

iVBORw0KGgoAAAANSUhEUgAAABYAAAAeCAMAAAAfOR5kAAAABGdBTUEAAL
GPC/xhBQAAAAd0SU1FB9gKDhAtOfvfKucAAAAYUExURf///wAAADMzM1tb
W4CAgKSkpMDAwP8AAEQE8ZoAAAABdFJOUwBA5thmAAAACXBIWXMAAA50AA
AOdAFrJLPWAAAAdElEQVQoU63Q0QrAIAgFUO/U9f9/vIxqpRIMdqOXQ6lF
RHBhsgAXs4zofXPzTZujlMayRjdmaMZDjXvtEy9FFp75zOXI/pX5n6D/lQ
v1WHnUJarTjGuRxpIxkLHtyIinx4tcy2S694Kjfzn2HDNqYM54H/wB55QF
O+Mp5mAAAAAASUVORK5CYII=

(and it contains just 8 colors, so it can be saved as a 4 bit PNG,
saving even more bytes). Generally I suggest to use as few bits/pixel
as possible, just 1 if possible.
For the encoding/decoding you can use str.encode("base64") and
str.decode("base64"), you don't need to import modules.

Bye,
bearophile

André

unread,
Oct 14, 2008, 9:31:26 PM10/14/08
to
On Oct 14, 1:56 pm, bearophileH...@lycos.com wrote:
> André:
>
> > Ok, the following is my first attempt at implementing this idea.
>
> I suggest you to change the program you use to encode your images,
> because it's 1000 bytes, while with my program the same 256 colors
> image needs just 278 bytes:
>
> iVBORw0KGgoAAAANSUhEUgAAABYAAAAeCAMAAAAfOR5kAAAABGdBTUEAAL
> GPC/xhBQAAAAd0SU1FB9gKDhAtOfvfKucAAAAYUExURf///wAAADMzM1tb
> W4CAgKSkpMDAwP8AAEQE8ZoAAAABdFJOUwBA5thmAAAACXBIWXMAAA50AA
> AOdAFrJLPWAAAAdElEQVQoU63Q0QrAIAgFUO/U9f9/vIxqpRIMdqOXQ6lF
> RHBhsgAXs4zofXPzTZujlMayRjdmaMZDjXvtEy9FFp75zOXI/pX5n6D/lQ
> v1WHnUJarTjGuRxpIxkLHtyIinx4tcy2S694Kjfzn2HDNqYM54H/wB55QF
> O+Mp5mAAAAAASUVORK5CYII=
>
> (and it contains just 8 colors, so it can be saved as a 4 bit PNG,
> saving even more bytes). Generally I suggest to use as few bits/pixel
> as possible, just 1 if possible.

While I agree that embedded images should be as small as possible,
this,
I believe, should be left entirely to the user. The code sample I
gave
was just a proof of concept - something people asked for on this list.

> For the encoding/decoding you can use str.encode("base64") and
> str.decode("base64"), you don't need to import modules.
>

Good suggestion.

> Bye,
> bearophile

A more complete example is now available at
http://code.activestate.com/recipes/576538/

André

(Of course, now I'll have to include this in Crunchy... ;-)

Aaron "Castironpi" Brady

unread,
Oct 14, 2008, 11:17:35 PM10/14/08
to

+.5 docpicture. For encoding, it might read in from a file, try
multiple different formats, including SVG, and uses whichever one is
shortest. It might be nice, if they take too many lines, to store
them at the end of the file, and make sure docpicture looks for them
there. It could be more hassle (maybe less, actually), to store them
as attributes of the objects they're accompanying, and still locate
them at the bottom-- sort of like an appendix or something.

def foo():
code code
def bar():
'''doc str'''
code code

foo.__docpic__= '''
hexhexhex
hexhexhex'''
bar.__docpic__= '''
hexhexhex'''

bearoph...@lycos.com

unread,
Oct 14, 2008, 11:54:49 PM10/14/08
to
André:

> A more complete example is now available at
> http://code.activestate.com/recipes/576538/

Nice.


>The idea for this recipe was mentioned on the Python mailing list as something desirable and apparently done by someone<

That someone has a nickname you can use, I am known in the cookbook
too :-)

Bye,
bearophile

Pete Forman

unread,
Oct 15, 2008, 11:06:06 AM10/15/08
to
Scott David Daniels <Scott....@Acm.Org> writes:

> or you could even use:
> '''<docpicture name="fig1.png" code="base64" version="1">
> 1234567890ABCDEF...
> </docpicture>'''
> A comment _not_ a docstring (only found by scanning the source).
> which is easy enough to hunt for.

-1 for XML based syntax, we should instead look to reST. It already
has image and figure directives. The docs say that image takes a URI
argument and some options. So an external file should work now.
Maybe someone would like to play with the data URL scheme (RFC 2397)
to meet the OP's desire to embed the image. AFAIK a downside is that
MS are only starting to support that in IE8.
--
Pete Forman -./\.- Disclaimer: This post is originated
WesternGeco -./\.- by myself and does not represent
pete....@westerngeco.com -./\.- the opinion of Schlumberger or
http://petef.22web.net -./\.- WesternGeco.

Lawrence D'Oliveiro

unread,
Oct 17, 2008, 3:53:01 AM10/17/08
to
In message <y70pki...@wgmail2.gatwick.eur.slb.com>, Pete Forman wrote:

> Maybe someone would like to play with the data URL scheme (RFC 2397)
> to meet the OP's desire to embed the image. AFAIK a downside is that
> MS are only starting to support that in IE8.

Firefox, Konqueror and Safari already support it. So it's not as though
users of all major platforms cannot access it.

0 new messages