473,396 Members | 2,011 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

docpicture

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
Oct 13 '08 #1
16 1047
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
Oct 13 '08 #2

StevenI can't imagine Python having direct syntactic support for it,
Stevenbut I don't see any reason why the standard library couldn't
Stevensome day grow a "docpicture" module, complete with a tiny (?)
StevenTkinter 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
Oct 13 '08 #3

BenjaminSo, the IDEs will support it. what happens when you run the
Benjamininterpreter 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
Oct 13 '08 #4
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

Oct 13 '08 #5
>Nothing. It's just a doc string containing a bunch of hex codes. Doc
>strings are ignored by the interpreter (AIUI).
BenjaminI mean what happens when you type help() into the interactive
Benjaminconsole on the command line? You will see the docstrings, and
Benjaminthere 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

Oct 13 '08 #6
On Mon, 13 Oct 2008 16:41:58 -0500, skip wrote:
>>Nothing. It's just a doc string containing a bunch of hex codes. Doc
strings are ignored by the interpreter (AIUI).

BenjaminI mean what happens when you type help() into the
interactive Benjaminconsole on the command line? You will see the
docstrings, and Benjaminthere 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.
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
Oct 13 '08 #7
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
Sc***********@Acm.Org
Oct 14 '08 #8
On Tue, 14 Oct 2008 06:12:59 -0700, Scott David Daniels wrote:
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.
+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
Oct 14 '08 #9
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
Oct 14 '08 #10
On Oct 14, 10:58*am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.auwrote:
On Tue, 14 Oct 2008 06:12:59 -0700, Scott David Daniels wrote:
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.

+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
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 = """\
iVBORw0KGgoAAAANSUhEUgAAABYAAAAeCAMAAAAfOR5kAAAACX BIWXMAAA7EAAAOxAGVKw4bAAAD
AFBMVEUAAAAzMzNbW1v/AACAgICkpKTAwMD///
8AAAAS8uhyd1MAAAABD3UAADYAAAAAAFAAABkA
AAGFBJ4AAAkAADYAAAAAAFAAABkAAAAAAAAAABQAABcAAAkAAA QAAAQAAAQAAATxogDxoeQBD3UA
ADkAAAMAABMAABMBDusAAAAAACYFDpQAAAAAACaqAAD///
8V5iAV5hgS9XC1WqAS85wBDwG2L+RF
NyAAABMAABMBDutPyjgS9CC1WqC1VShP0RYAAABPyji1WqAS9C C1RBxP7jMAAAIBD3UAADkAAAMA
ABMAABMV5iAS9BhBx0G1DExCx4VCx43LD8i1DGxFM5sS9BhFM7 JFM7oS9LRFM8QS9BgS9JjLD8jL
D8i1WqAS9DBCWLYABAEAAAC6Z1AAAAES9FzUhzRTBRAABAEAAA C6Z1DLD8i6q80AAAAS9JgS9HTU
tqPUhPzUhaQDBRoAAAEWIagWIcgABAAWX8gAAADUtik94ZFTBR AS9SwAAAAWX8g94ZwAAAAAAAAA
BAAAABMS9RAS9TjXBGfUiDD////UiCrUuJsAAADLD8hTBRAABAEAAAC6Z1B
+cqwAAAEAAAAAAAAA
AAAAAACKACEABADV8+N+cph
+8XAAAAAAAAQAAaYAAAIABAAAABMWIcgBCJ4AAAAAAAAAAAAAA AAA
AAAAAAAAAAAS8HSAFjwAAAUAAAVI2FSAGByAGKxI2GAAb1oS9f w97BsWX8gAAAAWIUgAAAQAAAAS
9mQ95ZgAAADXIloAAAAS9bzUtqPUhPzUhaQDBRoAAAEAAAAWX8 gWIUgDBQES9dDUwr8S9gA90ZMD
BRo95ZgWX8jUiKYAAAAAAAIAAMgAABMWIVAS9ijUhzRTBRAAAA 8AAAAAAAA95Zi6q80AAAAS9mQ9
5ZgS9pDUi9n90AAS9pDUiFoS9lDUiCoAAA895ZgS
+WgAABQAAAEAAAAAAAAAABAAAAAAAFAAAAEA
AAAAAAAS9kTxbGQS+TjXBGfUiDD////UiCoAAAAAAADKTwNHAAAACHRSTlP/////////
AN6DvVkA
AAB6SURBVHjardCLCsAgCAXQO7P8/z
+eyVxWEgzmKNghfEEES5CoqV5E7FFbIzKOao5SjJknj0yo
Gbt2fnKfOCQJHEt+43Lkdcp8J8bbBmEb7Jemh35cq/07axJjzhjIuJ+dsb/
2iZaSc3fO3qO88T+P
mpF5TB+YMp4bvwEGcAqR53QgIgAAAABJRU5ErkJggg==

"""

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

Oct 14 '08 #11
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:

iVBORw0KGgoAAAANSUhEUgAAABYAAAAeCAMAAAAfOR5kAAAABG dBTUEAAL
GPC/xhBQAAAAd0SU1FB9gKDhAtOfvfKucAAAAYUExURf///wAAADMzM1tb
W4CAgKSkpMDAwP8AAEQE8ZoAAAABdFJOUwBA5thmAAAACXBIWX MAAA50AA
AOdAFrJLPWAAAAdElEQVQoU63Q0QrAIAgFUO/U9f9/vIxqpRIMdqOXQ6lF
RHBhsgAXs4zofXPzTZujlMayRjdmaMZDjXvtEy9FFp75zOXI/pX5n6D/lQ
v1WHnUJarTjGuRxpIxkLHtyIinx4tcy2S694Kjfzn2HDNqYM54 H/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
Oct 14 '08 #12
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:

iVBORw0KGgoAAAANSUhEUgAAABYAAAAeCAMAAAAfOR5kAAAABG dBTUEAAL
GPC/xhBQAAAAd0SU1FB9gKDhAtOfvfKucAAAAYUExURf///wAAADMzM1tb
W4CAgKSkpMDAwP8AAEQE8ZoAAAABdFJOUwBA5thmAAAACXBIWX MAAA50AA
AOdAFrJLPWAAAAdElEQVQoU63Q0QrAIAgFUO/U9f9/vIxqpRIMdqOXQ6lF
RHBhsgAXs4zofXPzTZujlMayRjdmaMZDjXvtEy9FFp75zOXI/pX5n6D/lQ
v1WHnUJarTjGuRxpIxkLHtyIinx4tcy2S694Kjfzn2HDNqYM54 H/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... ;-)
Oct 15 '08 #13
On Oct 14, 11:56*am, 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:

iVBORw0KGgoAAAANSUhEUgAAABYAAAAeCAMAAAAfOR5kAAAABG dBTUEAAL
GPC/xhBQAAAAd0SU1FB9gKDhAtOfvfKucAAAAYUExURf///wAAADMzM1tb
W4CAgKSkpMDAwP8AAEQE8ZoAAAABdFJOUwBA5thmAAAACXBIWX MAAA50AA
AOdAFrJLPWAAAAdElEQVQoU63Q0QrAIAgFUO/U9f9/vIxqpRIMdqOXQ6lF
RHBhsgAXs4zofXPzTZujlMayRjdmaMZDjXvtEy9FFp75zOXI/pX5n6D/lQ
v1WHnUJarTjGuRxpIxkLHtyIinx4tcy2S694Kjfzn2HDNqYM54 H/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
+.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'''
Oct 15 '08 #14
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
Oct 15 '08 #15
Scott David Daniels <Sc***********@Acm.Orgwrites:
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
pe*********@westerngeco.com -./\.- the opinion of Schlumberger or
http://petef.22web.net -./\.- WesternGeco.
Oct 15 '08 #16
In message <y7**********@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.
Oct 17 '08 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: =?ISO-8859-1?Q?Andr=E9?= | last post by:
Docpicture 0.2 has been released. You can download it from http://code.google.com/p/docpicture/ Docpicture's goal is to enable embedding pictures inside Python docstrings using some custom...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.